Scripts/ingame-manual.js |
"use strict";
this.author = "cim";
this.copyright = "� 2011-2014 cim.";
this.licence = "CC-BY-SA 3.0";
this.version = "0.9.1";
this.name = "Ships Library";
this.description = "An e-book library readable on the F4 screen";
/* Public */
this._registerBook = function (key, title, contents) {
this.$books[key] = { title: title, contents: contents };
}
this._unregisterBook = function (key) {
if (key == "ingame-manual") {
return false; // can't remove this one
}
if (this.$currentBook == key) {
if (mission.screenID == "ships-library") {
// book is currently loaded and mission screen active
return false;
}
this._setBook("ingame-manual");
}
delete this.$books[key];
return true;
}
this.startUp = function () {
delete this.startUp;
this.$fcbM = false;
this.$hudHidden = false;
this.$manualActive = false;
this.$currentBook = false;
this.$spaceWidth = defaultFont.measureString(" ");
// settings for mission screen reading
this.$chapter = 0;
this.$offset = 0;
this.$msStore = "offsets";
this.$msRows = 15;
this.$msCols = 32;
// settings for MFD in-flight reading
this.$mfdChapter = 0;
this.$mfdOffset = 0;
this.$mfdStore = "miniOffsets";
this.$mfdRows = 10;
this.$mfdCols = 14.75;
this.$mfdMode = 0;
this.$mfdOn = false;
// initialise
this.$minblock = 3;
this.$chaptersperpage = 20;
this.$books = new Object;
this._registerIngameManual();
this.$mode = "firstrun";
if (missionVariables.ships_library_bookmark) {
this.$bookmark = JSON.parse(missionVariables.ships_library_bookmark);
} else {
this.$bookmark = { "ingame-manual": [0, 0, 0, 0] };
}
this._setBook("ingame-manual");
}
this.startUpComplete = function () {
this._initInterface(system.mainStation);
this._initInterface(player.ship.dockedStation);
}
/* Private and handlers */
this.playerWillSaveGame = function () {
missionVariables.ships_library_bookmark = JSON.stringify(this.$bookmark);
}
this.shipDockedWithStation = function (station) {
this._initInterface(station);
}
this._initInterface = function (station) {
station.setInterface(this.name, {
title: expandMissionText("ships-library-title"),
category: expandDescription("[interfaces-category-ship-systems]"),
summary: expandMissionText("ships-library-summary"),
callback: this._showLibrary.bind(this)
});
}
this._registerIngameManual = function () {
var contents = [
{ level: 0, key: "ingame-manual-frontpage", params: [this._getTip], opts: { model: "[" + player.ship.dataKey + "]", spinModel: false } },
{ level: 0, key: "ingame-manual-welcome" },
{ level: 0, key: "ingame-manual-controls" },
{ level: 1, key: "ingame-manual-ship-systems" },
{ level: 2, key: "ingame-manual-ship-systems-status", backgrounds: ["ingame-manual-f5.png", ""] },
{ level: 2, key: "ingame-manual-ship-systems-manifest", backgrounds: ["ingame-manual-f5f5.png", ""] },
{ level: 2, key: "ingame-manual-ship-systems-src", backgrounds: ["ingame-manual-f6.png", ""] },
{ level: 2, key: "ingame-manual-ship-systems-lrc", backgrounds: ["ingame-manual-f6f6.png", ""] },
{ level: 2, key: "ingame-manual-ship-systems-planet", backgrounds: ["ingame-manual-f7.png", ""] },
{ level: 2, key: "ingame-manual-ship-systems-commodity", params: [function () { return player.ship.cargoSpaceCapacity; }], backgrounds: ["ingame-manual-f8.png", ""] },
{ level: 1, key: "ingame-manual-station-systems" },
{ level: 2, key: "ingame-manual-station-systems-launch", backgrounds: ["ingame-manual-f1.png"] },
{ level: 2, key: "ingame-manual-station-systems-equipment", backgrounds: ["ingame-manual-f3.png", ""] },
{ level: 2, key: "ingame-manual-station-systems-shipyard", backgrounds: ["ingame-manual-f3f3.png", ""] },
{ level: 2, key: "ingame-manual-station-systems-interfaces", backgrounds: ["ingame-manual-f4.png", ""] },
{ level: 1, key: "ingame-manual-inflight" },
{ level: 2, key: "ingame-manual-inflight-view" },
{ level: 2, key: "ingame-manual-inflight-hud", params: [function () { return Math.max(1, Math.floor(player.ship.maxEnergy / 64)); }], backgrounds: ["ingame-manual-hud.png"] },
{ level: 3, key: "ingame-manual-inflight-hud-scanner", backgrounds: ["ingame-manual-hud.png"] },
{ level: 2, key: "ingame-manual-inflight-flight" },
{ level: 2, key: "ingame-manual-inflight-docking", backgrounds: ["ingame-manual-dock0.png", "ingame-manual-dock1.png", "ingame-manual-dock2.png", "ingame-manual-dock3.png", "ingame-manual-dock4.png"] },
{ level: 2, key: "ingame-manual-inflight-navigation", params: [function () { if (player.ship.hasHyperspaceMotor) { return expandDescription("[ingame-manual-hyperspaceinfo]", { "spintime": player.ship.hyperspaceSpinTime }); } else { return "" } }, function () { if (player.ship.hasHyperspaceMotor) { return expandDescription("[ingame-manual-outoffuel]"); } else { return expandDescription("[ingame-manual-nohyperdrive]") } }] },
{ level: 2, key: "ingame-manual-inflight-combat" },
{ level: 3, key: "ingame-manual-inflight-combat-laser", params: [function () { var m = player.ship.weaponFacings; return (m & 1) + ((m & 2) / 2) + ((m & 4) / 4) + ((m & 8) / 8); }], backgrounds: ["ingame-manual-laser0.png"] },
{ level: 3, key: "ingame-manual-inflight-combat-missile", params: [function () { return player.ship.missileCapacity; }], backgrounds: ["ingame-manual-missile0.png"] },
{ level: 0, key: "ingame-manual-equipment" },
{ level: 1, key: "ingame-manual-equipment-standard" },
{ level: 2, key: "ingame-manual-equipment-standard-hull" },
{ level: 2, key: "ingame-manual-equipment-standard-generators" },
{ level: 2, key: "ingame-manual-equipment-standard-capacitors", params: [function () { return Math.ceil(player.ship.maxEnergy / 64); }] },
{ level: 2, key: "ingame-manual-equipment-standard-support" },
{ level: 2, key: "ingame-manual-equipment-standard-crew" },
{ level: 2, key: "ingame-manual-equipment-standard-engines" },
{ level: 2, key: "ingame-manual-equipment-standard-shields" },
{ level: 2, key: "ingame-manual-equipment-standard-sensors" },
{ level: 2, key: "ingame-manual-equipment-standard-cargo" },
{ level: 2, key: "ingame-manual-equipment-standard-witchdrive" },
{ level: 1, key: "ingame-manual-equipment-trading" },
{ level: 2, key: "ingame-manual-equipment-trading-cargo" },
{ level: 2, key: "ingame-manual-equipment-trading-scoops", backgrounds: ["ingame-manual-scoops0.png", "ingame-manual-scoops1.png"] },
{ level: 2, key: "ingame-manual-equipment-trading-heat", backgrounds: ["ingame-manual-heat.png"] },
{ level: 2, key: "ingame-manual-equipment-trading-passenger" },
{ level: 2, key: "ingame-manual-equipment-trading-ana", backgrounds: ["ingame-manual-ana.png"] },
{ level: 2, key: "ingame-manual-equipment-trading-asc", backgrounds: ["ingame-manual-asc.png"] },
{ level: 2, key: "ingame-manual-equipment-trading-docking" },
{ level: 2, key: "ingame-manual-equipment-trading-galactic" },
{ level: 1, key: "ingame-manual-equipment-combat" },
{ level: 2, key: "ingame-manual-equipment-combat-lasers", backgrounds: ["ingame-manual-laser1.png"] },
{ level: 3, key: "ingame-manual-equipment-combat-lasers-pulse" },
{ level: 3, key: "ingame-manual-equipment-combat-lasers-beam" },
{ level: 3, key: "ingame-manual-equipment-combat-lasers-mining" },
{ level: 3, key: "ingame-manual-equipment-combat-lasers-military" },
{ level: 2, key: "ingame-manual-equipment-combat-pylons", backgrounds: ["ingame-manual-pylons0.png"] },
{ level: 3, key: "ingame-manual-equipment-combat-pylons-missile", backgrounds: ["ingame-manual-missile1.png"] },
{ level: 3, key: "ingame-manual-equipment-combat-pylons-hardhead", opts: { model: "[ecm-proof-missile]" } },
{ level: 3, key: "ingame-manual-equipment-combat-pylons-qcm", opts: { model: "[qbomb]" } },
{ level: 2, key: "ingame-manual-equipment-combat-ecm" },
{ level: 2, key: "ingame-manual-equipment-combat-mts", backgrounds: ["ingame-manual-pylons1.png"] },
{ level: 2, key: "ingame-manual-equipment-combat-escape", opts: { model: "[escape-capsule]" } },
{ level: 2, key: "ingame-manual-equipment-combat-eeu" },
{ level: 2, key: "ingame-manual-equipment-combat-tsme" },
{ level: 2, key: "ingame-manual-equipment-combat-inject", backgrounds: ["ingame-manual-inject.png"] },
{ level: 2, key: "ingame-manual-equipment-combat-wormhole", backgrounds: ["ingame-manual-wormhole.png"] },
{ level: 2, key: "ingame-manual-equipment-combat-ste", backgrounds: ["ingame-manual-ste.png"] },
{ level: 2, key: "ingame-manual-equipment-combat-its" },
{ level: 2, key: "ingame-manual-equipment-combat-shield" },
{ level: 1, key: "ingame-manual-equipment-extra" },
{ level: 2, key: "ingame-manual-equipment-extra-displays" },
{ level: 0, key: "ingame-manual-sociology" },
{ level: 1, key: "ingame-manual-sociology-galcop" },
{ level: 2, key: "ingame-manual-sociology-galcop-facilities", backgrounds: ["ingame-manual-station.png"] },
{ level: 2, key: "ingame-manual-sociology-galcop-legal", backgrounds: ["ingame-manual-police0.png", "ingame-manual-police1.png", "ingame-manual-police0.png"] },
{ level: 2, key: "ingame-manual-sociology-galcop-combat", backgrounds: ["ingame-manual-combat0.png"] },
{ level: 1, key: "ingame-manual-sociology-pilots" },
{ level: 2, key: "ingame-manual-sociology-pilots-traders", backgrounds: ["ingame-manual-shiptrader.png"] },
{ level: 2, key: "ingame-manual-sociology-pilots-hunters", backgrounds: ["ingame-manual-shiphunter.png"] },
{ level: 2, key: "ingame-manual-sociology-pilots-pirates", backgrounds: ["ingame-manual-shippirate.png"] },
{ level: 2, key: "ingame-manual-sociology-pilots-miners", backgrounds: ["ingame-manual-shipminer.png"] },
{ level: 2, key: "ingame-manual-sociology-pilots-military" },
{ level: 2, key: "ingame-manual-sociology-pilots-deep" },
{ level: 2, key: "ingame-manual-sociology-pilots-salvage" },
{ level: 1, key: "ingame-manual-sociology-govt" },
{ level: 2, key: "ingame-manual-sociology-govt-corp" },
{ level: 2, key: "ingame-manual-sociology-govt-demo" },
{ level: 2, key: "ingame-manual-sociology-govt-conf" },
{ level: 2, key: "ingame-manual-sociology-govt-comm" },
{ level: 2, key: "ingame-manual-sociology-govt-dict" },
{ level: 2, key: "ingame-manual-sociology-govt-mult" },
{ level: 2, key: "ingame-manual-sociology-govt-feud" },
{ level: 2, key: "ingame-manual-sociology-govt-anar" },
{ level: 1, key: "ingame-manual-sociology-econ" },
{ level: 2, key: "ingame-manual-sociology-econ-agri" },
{ level: 2, key: "ingame-manual-sociology-econ-ind" },
{ level: 1, key: "ingame-manual-sociology-species" },
{ level: 1, key: "ingame-manual-sociology-thargoids" },
{ level: 1, key: "ingame-manual-sociology-history" },
{ level: 2, key: "ingame-manual-sociology-history-before" },
{ level: 2, key: "ingame-manual-sociology-history-eight" },
{ level: 2, key: "ingame-manual-sociology-history-interspecies" },
{ level: 2, key: "ingame-manual-sociology-history-founding" },
{ level: 2, key: "ingame-manual-sociology-history-thargoids" },
{ level: 2, key: "ingame-manual-sociology-history-modern" },
{ level: 0, key: "ingame-manual-ships" },
{ level: 1, key: "ingame-manual-ships-adder", opts: { model: "[adder]" } },
{ level: 1, key: "ingame-manual-ships-anaconda", opts: { model: "[anaconda]" } },
{ level: 1, key: "ingame-manual-ships-asp", opts: { model: "[asp]" } },
{ level: 1, key: "ingame-manual-ships-boa", opts: { model: "[boa]" } },
{ level: 1, key: "ingame-manual-ships-boa2", opts: { model: "[boa-mk2]" } },
{ level: 1, key: "ingame-manual-ships-cobra", opts: { model: "[cobramk1]" } },
{ level: 1, key: "ingame-manual-ships-cobra3", opts: { model: "[cobra3-trader]" } },
{ level: 1, key: "ingame-manual-ships-fdl", opts: { model: "[ferdelance]" } },
{ level: 1, key: "ingame-manual-ships-gecko", opts: { model: "[gecko]" } },
{ level: 1, key: "ingame-manual-ships-krait", opts: { model: "[krait]" } },
{ level: 1, key: "ingame-manual-ships-mamba", opts: { model: "[mamba]" } },
{ level: 1, key: "ingame-manual-ships-moray", opts: { model: "[moray]" } },
{ level: 1, key: "ingame-manual-ships-shuttle", opts: { model: "[shuttle]" } },
{ level: 1, key: "ingame-manual-ships-python", opts: { model: "[python]" } },
{ level: 1, key: "ingame-manual-ships-sidewinder", opts: { model: "[sidewinder]" } },
{ level: 1, key: "ingame-manual-ships-transporter", opts: { model: "[transporter-miner]" } },
{ level: 1, key: "ingame-manual-ships-viper", opts: { model: "[viper]" } },
{ level: 1, key: "ingame-manual-ships-interceptor", opts: { model: "[viper-interceptor]" } },
{ level: 1, key: "ingame-manual-ships-worm", opts: { model: "[worm]" } },
{ level: 1, key: "ingame-manual-ships-thargoid", opts: { model: "[thargoid]" } },
{ level: 1, key: "ingame-manual-ships-tharglet", opts: { model: "[tharglet]" } },
{ level: 0, key: "ingame-manual-end" } // temp entry
];
this._registerBook("ingame-manual", expandMissionText("ingame-manual-title"), contents);
}
this._setBook = function (key) {
if (!this.$books[key]) {
return;
}
this.$contents = this.$books[key].contents;
if (!this.$fcb) {
this.$fcb = addFrameCallback(this._precalculateOffsets.bind(this));
}
if (this.$bookmark[key]) {
while (this.$bookmark[key].length < 4) {
this.$bookmark[key].push(0);
}
this.$chapter = this.$bookmark[key][0];
this.$offset = this.$bookmark[key][1];
this.$mfdChapter = this.$bookmark[key][2];
this.$mfdOffset = this.$bookmark[key][3];
} else {
this.$chapter = 0;
this.$offset = 0;
this.$mfdChapter = 0;
this.$mfdOffset = 0;
this.$bookmark[key] = [0, 0, 0, 0];
}
this.$currentBook = key;
// reset MFD if active
if (!player.ship.docked) {
this.$mfdOn = false;
this.$mfdMode = 0;
player.consoleMessage("Ship's Library interface reset", 6);
this._hideMFD();
}
}
this._getBookListAlpha = function () {
var keys = Object.keys(this.$books);
keys.sort(function (a, b) {
return this.$books[a].title.localeCompare(this.$books[b].title);
}.bind(this));
return keys;
}
/** Mission screen management **/
this._showLibrary = function () {
this.$mode = "firstrun";
// init and enter loop
this._showManual();
}
this._showManual = function () {
this.$hudHidden = player.ship.hudHidden;
this.$manualActive = true;
player.ship.hudHidden = true;
if (this.$mode == "firstrun") {
if (Object.keys(this.$books).length > 1) {
this.$mode = "book";
this.$offset = 0;
} else {
this.$mode = "read";
}
}
if (this.$mode == "contents") {
this._showChapterList();
} else if (this.$mode == "read") {
this._showPage();
} else if (this.$mode == "book") {
this._showBookList();
}
}
this.guiScreenChanged = function (to, from) {
if (from == "GUI_SCREEN_MISSION" && this.$manualActive) {
this.$manualActive = false;
player.ship.hudHidden = this.$hudHidden;
if (this.$fcbM) {
removeFrameCallback(this.$fcbM);
delete this.$fcbM;
}
}
}
this._showBookList = function () {
var blank = { unselectable: true, text: "" };
var listchoices = new Object;
if (this.$offset >= this.$chaptersperpage) {
listchoices["51_BOOK_BACK"] = {
text: expandMissionText("ships-library-contents-back"),
alignment: "LEFT",
color: "orangeColor"
}
} else {
listchoices["51_BOOK_BACK"] = blank;
}
listchoices["53_SPACER"] = blank;
var books = this._getBookListAlpha();
var start = this.$offset - (this.$offset % this.$chaptersperpage);
for (var i = start; i < start + this.$chaptersperpage; i++) {
var istr = String(i);
if (i < 10) {
istr = "0" + String(i);
}
if (books.length > i) {
listchoices["55_BOOK_SELECT_" + istr + "_" + books[i]] = {
text: this.$books[books[i]].title,
alignment: "LEFT"
}
} else {
listchoices["55_BOOK_SELECT_" + istr + "_"] = blank;
}
}
listchoices["57_SPACER"] = blank;
if (start + this.$chaptersperpage < books.length) {
listchoices["59_BOOK_FORWARD"] = {
text: expandMissionText("ships-library-contents-forward"),
alignment: "RIGHT",
color: "orangeColor"
}
} else {
listchoices["59_CONTENTS_FORWARD"] = blank;
}
for (var i = 24; i < 26; i++) {
listchoices["98_SPACER" + i] = blank;
}
// listchoices["50_BOOK"] = expandMissionText("ships-library-changebook");
listchoices["99_EXIT"] = expandMissionText("ships-library-exit");
mission.runScreen({
screenID: "ships-library",
titleKey: "ships-library-bookselect",
allowInterrupt: true,
exitScreen: "GUI_SCREEN_INTERFACES",
choices: listchoices,
initialChoicesKey: this.$lastchoice ? this.$lastchoice : "55_CONTENTS_SELECT_" + this.$offset
}, this._manualHandler, this);
}
this._showChapterList = function () {
// 0 = back in list (?)
// 2-11 = chapter headings (read chapter)
// 13 = forward in list (?)
// 20 = exit
var blank = { unselectable: true, text: "" };
var listchoices = new Object;
if (this.$chapter >= this.$chaptersperpage) {
listchoices["11_CONTENTS_BACK"] = {
text: expandMissionText("ships-library-contents-back"),
alignment: "LEFT",
color: "orangeColor"
}
} else {
listchoices["11_CONTENTS_BACK"] = blank;
}
listchoices["13_SPACER"] = blank;
var start = this.$chapter - (this.$chapter % this.$chaptersperpage);
for (var i = start; i < start + this.$chaptersperpage; i++) {
var istr = String(i);
if (i < 10) {
istr = "0" + String(i);
}
if (this.$contents.length > i) {
var indent = "";
if (this.$contents[i].level > 0) {
indent += Array(this.$contents[i].level + 1).join("... ");
}
listchoices["15_CONTENTS_SELECT_" + istr] = {
text: indent + expandMissionText(this.$contents[i].key + "-title"),
alignment: "LEFT"
}
} else {
listchoices["15_CONTENTS_SELECT_" + istr] = blank;
}
}
listchoices["17_SPACER"] = blank;
if (start + this.$chaptersperpage < this.$contents.length) {
listchoices["19_CONTENTS_FORWARD"] = {
text: expandMissionText("ships-library-contents-forward"),
alignment: "RIGHT",
color: "orangeColor"
}
} else {
listchoices["19_CONTENTS_FORWARD"] = blank;
}
for (var i = 24; i < 25; i++) {
listchoices["48_SPACER" + i] = blank;
}
listchoices["50_BOOK"] = expandMissionText("ships-library-changebook");
listchoices["99_EXIT"] = expandMissionText("ships-library-exit");
mission.runScreen({
screenID: "ships-library",
titleKey: "ships-library-chapterselect",
allowInterrupt: true,
exitScreen: "GUI_SCREEN_INTERFACES",
choices: listchoices,
initialChoicesKey: this.$lastchoice ? this.$lastchoice : "15_CONTENTS_SELECT_" + this.$chapter
}, this._manualHandler, this);
}
this._showPage = function () {
var chapter = this.$contents[this.$chapter];
var text = this._textFromOffset(this.$chapter, this.$offset, this.$msStore, this.$msRows, this.$msCols);
var opts = {
screenID: "ships-library",
titleKey: chapter.key + "-title",
allowInterrupt: true,
exitScreen: "GUI_SCREEN_INTERFACES",
choices: {
"01_PREV": expandMissionText("ships-library-page-back"),
"09_NEXT": expandMissionText("ships-library-page-next"),
"10_CONTENTS": expandMissionText("ships-library-contents"),
"99_EXIT": expandMissionText("ships-library-exit"),
},
initialChoicesKey: this.$lastchoice ? this.$lastchoice : "09_NEXT",
message: text
};
if (chapter.opts) {
var extras = Object.keys(chapter.opts)
for (var k = 0; k < extras.length; k++) {
opts[extras[k]] = chapter.opts[extras[k]];
}
}
if (chapter.backgrounds) {
var page = this._pageOfOffset(chapter, this.$offset, this.$msStore);
if (page < chapter.backgrounds.length) {
var backg = chapter.backgrounds[page];
} else {
var backg = chapter.backgrounds[chapter.backgrounds.length - 1];
}
if (backg != "") {
opts.overlay = backg;
}
}
mission.runScreen(opts, this._manualHandler, this);
this.$fcbM = addFrameCallback(this._moveShip.bind(this));
}
this._moveShip = function (delta) {
if (mission.displayModel) {
if (mission.displayModel.position.y >= -1) {
mission.displayModel.position = new Vector3D(0, -mission.displayModel.position.z / 2.5, mission.displayModel.position.z * 2.5);
}
}
}
this._setBookmark = function () {
this.$bookmark[this.$currentBook][0] = this.$chapter;
this.$bookmark[this.$currentBook][1] = this.$offset;
this.$bookmark[this.$currentBook][2] = this.$mfdChapter;
this.$bookmark[this.$currentBook][3] = this.$mfdOffset;
}
this._manualHandler = function (choice) {
// log(this.name,choice);
delete this.$lastchoice;
if (!choice) {
return; // launched while reading?
} else if (choice == "01_PREV") {
if (this.$offset == 0) {
if (this.$chapter == 0) {
this.$mode = "contents";
} else {
this.$mode = "read";
this.$chapter--;
this.$offset = this._lastPageOffset(this.$chapter, this.$msStore);
this._setBookmark();
}
} else {
this.$mode = "read";
this.$offset = this._previousOffset(this.$chapter, this.$offset, this.$msStore, this.$msRows, this.$msCols);
this._setBookmark();
}
this.$lastchoice = choice;
} else if (choice == "05_READ") {
this.$mode = "read";
} else if (choice == "09_NEXT") {
this.$offset = this._nextOffset(this.$chapter, this.$offset, this.$msStore, this.$msRows, this.$msCols);
if (this.$offset == -1) {
this.$offset = 0;
this.$chapter++;
if (this.$chapter >= this.$contents.length) {
this.$mode = "contents";
this.$chapter = 0;
} else {
this._setBookmark();
this.$mode = "read";
}
} else {
this._setBookmark();
}
} else if (choice == "10_CONTENTS") {
this.$mode = "contents";
this.$offset = 0;
} else if (choice == "11_CONTENTS_BACK") {
this.$mode = "contents";
this.$offset = 0;
this.$chapter -= 1 + (this.$chapter % this.$chaptersperpage);
this.$lastchoice = choice;
} else if (choice.match(/^15_CONTENTS_SELECT_/)) {
this.$chapter = parseInt(choice.slice(19), 10);
this.$offset = 0;
this._setBookmark();
this.$mode = "read";
} else if (choice == "19_CONTENTS_FORWARD") {
this.$mode = "contents";
this.$offset = 0;
this.$chapter += this.$chaptersperpage - (this.$chapter % this.$chaptersperpage);
this.$lastchoice = choice;
} else if (choice == "50_BOOK") {
this.$mode = "book";
this.$offset = 0;
} else if (choice == "51_BOOK_BACK") {
this.$offset -= this.$chaptersperpage;
} else if (choice == "59_BOOK_FORWARD") {
this.$offset += this.$chaptersperpage;
} else if (choice.match(/^55_BOOK_SELECT_/)) {
this._setBook(choice.slice(18));
this.$mode = "read";
}
// 01_PREV: reduce offset to prev page, or last page of prev chapter
// 05_READ: switch to read mode at current chapter + offset
// 09_NEXT: advance offset to next page, or next chapter if no more
// 10_CONTENTS: switch to contents mode at current chapter, zero offset
// 11_CONTENTS_BACK: up one page in chapter list
// 15_CONTENTS_SELECT_[0-9]: switch to read mode in chapter at offset
// 19_CONTENTS_FORWARD: down one page in chapter list
// 99_EXIT: quit
if (choice != "99_EXIT") {
this._showManual();
}
}
/** MFD functions **/
this._equipPressMode = function () {
this.$mfdMode = (this.$mfdMode + 1) % 7;
player.consoleMessage(expandDescription("[ships-library-mfd-mode][ships-library-mfd-mode" + this.$mfdMode + "]"));
}
this._equipPressActivate = function () {
if (player.ship.multiFunctionDisplays == 0) {
player.consoleMessage(expandDescription("[ships-library-mfd-unavailable]"));
return;
}
if (this.$mfdMode == 0) // power
{
this.$mfdOn = !this.$mfdOn;
if (this.$mfdOn) {
// out of range value picks first free MFD, if there is one
player.ship.setMultiFunctionDisplay(player.ship.multiFunctionDisplays, "ships-library")
player.consoleMessage(expandDescription("[ships-library-mfd-on]"));
}
}
else if (this.$mfdMode == 1) // next page
{
this.$mfdOffset = this._nextOffset(this.$mfdChapter, this.$mfdOffset, this.$mfdStore, this.$mfdRows, this.$mfdCols);
if (this.$mfdOffset == -1) {
this.$mfdOffset = 0;
this.$mfdChapter++;
if (this.$mfdChapter >= this.$contents.length) {
this.$mfdChapter = 0;
} else {
this._setBookmark();
}
} else {
this._setBookmark();
}
}
else if (this.$mfdMode == 2) // prev page
{
if (this.$mfdOffset == 0) {
if (this.$mfdChapter == 0) {
this.$mfdChapter = this.$contents.length - 1;
} else {
this.$mfdChapter--;
this.$mfdOffset = this._lastPageOffset(this.$mfdChapter, this.$mfdStore);
this._setBookmark();
}
} else {
this.$mfdOffset = this._previousOffset(this.$mfdChapter, this.$mfdOffset, this.$mfdStore, this.$mfdRows, this.$mfdCols);
this._setBookmark();
}
}
else if (this.$mfdMode == 3) // next chapter
{
this.$mfdOffset = 0;
this.$mfdChapter++;
if (this.$mfdChapter >= this.$contents.length) {
this.$mfdChapter = 0;
}
}
else if (this.$mfdMode == 4) // prev chapter
{
this.$mfdOffset = 0;
this.$mfdChapter--;
if (this.$mfdChapter < 0) {
this.$mfdChapter = this.$contents.length - 1;
}
}
else if (this.$mfdMode == 5) // next book
{
var booklist = Object.keys(this.$books);
var curIndex = booklist.indexOf(this.$currentBook);
var newIndex = curIndex + 1;
if (curIndex == booklist.length - 1) newIndex = 0;
this._setBook(booklist[newIndex]);
player.consoleMessage("Book selected: " + this.$books[booklist[newIndex]].title, 6);
}
else if (this.$mfdMode == 6) // previous book
{
var booklist = Object.keys(this.$books);
var curIndex = booklist.indexOf(this.$currentBook);
var newIndex = curIndex - 1;
if (curIndex == 0) newIndex = booklist.length - 1;
this._setBook(booklist[newIndex]);
player.consoleMessage("Book selected: " + this.$books[booklist[newIndex]].title, 6);
}
if (this.$mfdOn) {
this._showMFD();
}
else {
this._hideMFD();
}
}
this._showMFD = function () {
var text = this._textFromOffset(this.$mfdChapter, this.$mfdOffset, this.$mfdStore, this.$mfdRows, this.$mfdCols);
text = this._mfdBreak(text);
player.ship.setMultiFunctionText("ships-library", text);
}
this._hideMFD = function () {
player.ship.setMultiFunctionText("ships-library");
}
this._mfdBreak = function (text) {
if (text == String.fromCharCode(30)) {
return expandDescription("[ingame-library-imageunavailable]");
}
var linewidth = this.$mfdCols;
var lines = [];
var paras = text.split("\n");
var pl = paras.length;
for (var i = 0; i < pl; i++) {
var accum = "";
var words = paras[i].split(" ");
var widthuse = 0;
var wl = words.length;
for (var j = 0; j < wl; j++) {
var word = (accum == "" ? "" : " ") + words[j];
var wordwidth = defaultFont.measureString(word);
if (widthuse + wordwidth < linewidth) {
accum += word;
widthuse += wordwidth;
} else {
lines.push(accum);
accum = word.slice(1);
widthuse = wordwidth - this.$spaceWidth;
}
}
lines.push(accum);
}
return lines.join("\n");
}
/** Utility functions **/
this._blockFromOffset = function (chapternum, offset, lines, linewidth) {
// log(this.name,"Calculating block: "+key+","+offset);
var pagebreak = String.fromCharCode(30);
// var lines = this.$rows;
// var linewidth = this.$cols;
var fulltext = this._getText(chapternum);
var text = fulltext.slice(offset, offset + (lines * linewidth * 4));
var paras = text.split("\n");
var accum = "";
var lineuse = 0;
var pl = paras.length;
for (var i = 0; i < pl; i++) {
var words = paras[i].split(" ");
var widthuse = 0;
var wl = words.length;
for (var j = 0; j < wl; j++) {
if (words[j] == pagebreak) {
lineuse = lines;
accum += pagebreak + "\n";
break; // page break character
}
var word = (j == 0 ? "" : " ") + words[j];
var wordwidth = defaultFont.measureString(word);
if (widthuse + wordwidth < linewidth) {
accum += word;
widthuse += wordwidth;
} else {
widthuse = 0;
lineuse++;
if (lineuse >= lines) {
accum += "\n";
break;
} else {
accum += word;
if (j == 0) {
widthuse += wordwidth;
}
else {
widthuse += wordwidth - this.$spaceWidth;
}
}
}
}
if (lineuse >= lines) {
break;
}
lineuse++;
accum += "\n";
if (lineuse >= lines) {
break;
}
}
if (lineuse < this.$minblock && lines == this.$msRows) {
this.$short = true;
} else {
this.$short = false;
}
// log(this.name,"Calculated block: "+key+","+offset);
return accum;
}
// offset calculation can be fairly slow for large text blocks
// this calculates it in the background a page at a time
// while the player is docked and frame rate is less crucial
this._precalculateOffsets = function () {
if (!player.ship || !player.ship.docked) {
return;
}
for (var i = 0; i < this.$contents.length; i++) {
if (this._precalculateOffset(i)) {
return;
}
}
removeFrameCallback(this.$fcb);
delete this.$fcb;
}
this._precalculateOffset = function (chapternum) {
var chapter = this.$contents[chapternum];
if (chapter.offsets && chapter.miniOffsets) {
return false;
}
if (!chapter._offsets) {
chapter._offsets = [0];
}
if (!chapter._miniOffsets) {
chapter._miniOffsets = [0];
}
var fulltext = this._getText(chapternum);
var offset = chapter._offsets[chapter._offsets.length - 1];
var block = this._blockFromOffset(chapternum, offset, this.$msRows, this.$msCols);
offset += block.length;
if (offset < fulltext.length) {
// add next block
chapter._offsets.push(offset);
} else {
// done
if (this.$short && chapter._offsets.length > 1) {
chapter._offsets.pop(); // merge last block into previous
}
chapter._offsets.push(-1);
chapter.offsets = chapter._offsets;
delete chapter._offsets;
}
offset = chapter._miniOffsets[chapter._miniOffsets.length - 1];
block = this._blockFromOffset(chapternum, offset, this.$mfdRows, this.$mfdCols);
offset += block.length;
if (offset < fulltext.length) {
// add next block
chapter._miniOffsets.push(offset);
} else {
// done
if (this.$short && chapter._miniOffsets.length > 1) {
chapter._miniOffsets.pop(); // merge last block into previous
}
chapter._miniOffsets.push(-1);
chapter.miniOffsets = chapter._miniOffsets;
delete chapter._miniOffsets;
}
return true;
}
this._calculateOffsets = function (chapternum, rows, cols) {
var offsets = new Array;
var fulltext = this._getText(chapternum);
var offset = 0;
this.$short = false;
while (offset < fulltext.length && !this.$short) {
offsets.push(offset);
var block = this._blockFromOffset(chapternum, offset, rows, cols);
offset += block.length;
}
if (this.$short && offsets.length > 1) {
offsets.pop(); // merge last block into previous
}
offsets.push(-1);
return offsets;
}
this._textFromOffset = function (chapternum, fromoffset, otype, rows, cols) {
var fulltext = this._getText(chapternum);
var tooffset = this._nextOffset(chapternum, fromoffset, otype, rows, cols);
if (tooffset == -1) {
var slice = fulltext.slice(fromoffset);
} else {
var slice = fulltext.slice(fromoffset, tooffset);
}
return slice.trim();
}
this._getText = function (chapternum) {
var chapter = this.$contents[chapternum];
var params = new Object;
params["ships-library-page-break"] = String.fromCharCode(30) + "\n";
if (!chapter.params) {
return expandMissionText(chapter.key + "-text", params);
} else {
for (var i = 0; i < chapter.params.length; i++) {
params["ships_library_param_" + i] = chapter.params[i]();
}
return expandMissionText(chapter.key + "-text", params);
}
}
this._pageOfOffset = function (chapter, offset, otype) {
// only call this function when chapter.offsets must have been
// calculated already
for (var i = 0; i < chapter[otype].length; i++) {
if (offset <= chapter[otype][i]) {
return i;
}
}
return chapter[otype].length;
}
this._nextOffset = function (chapternum, fromoffset, otype, rows, cols) {
var chapter = this.$contents[chapternum];
if (!chapter[otype]) {
chapter[otype] = this._calculateOffsets(chapternum, rows, cols);
delete chapter._offsets;
}
for (var i = 0; i < chapter[otype].length; i++) {
if (fromoffset <= chapter[otype][i]) {
if (i == chapter[otype].length - 1) {
return -1;
}
return chapter[otype][i + 1];
}
}
return -1;
}
this._previousOffset = function (chapternum, fromoffset, otype, rows, cols) {
var offcount = 0;
do {
var next = this._nextOffset(chapternum, offcount, otype, rows, cols);
if (next < fromoffset) {
offcount = next;
}
} while (next < fromoffset);
return offcount;
}
this._lastPageOffset = function (chapternum, otype, rows, cols) {
var offcount = 0;
do {
var next = this._nextOffset(chapternum, offcount, otype, rows, cols);
if (next != -1) {
offcount = next;
}
} while (next != -1);
return offcount;
}
this._getTip = function () {
var numtips = 12;
var tipn = (clock.days - 2084004) % numtips;
if (tipn <= 9) {
var tips = "00" + tipn.toString();
} else if (tipn <= 99) {
var tips = "0" + tipn.toString();
} else {
var tips = tipn.toString();
}
return expandMissionText("ingame-manual-tip-" + tips);
}
|