Scripts/ingame-manual.js |
"use strict";
this.author = "cim";
this.copyright = "� 2011-2014 cim.";
this.licence = "CC-BY-SA 3.0";
this.version = "0.8";
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 = "offset";
this.$msRows = 15;
this.$msCols = 32;
// settings for MFD in-flight reading
this.$mfdChapter = 0;
this.$mfdOffset = 0;
this.$mfdStore = "miniOffset";
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("You have already been introduced to the short range chart for selecting a witchspace destination. Provided the destination is within range, you have sufficient fuel, and you are sufficiently clear of large objects for safety reasons, you can activate the witchdrive by pressing '[oolite_key_hyperspace]'. The drive will take "+player.ship.hyperspaceSpinTime+" seconds to power up and prepare for the jump. During this time it is recommended to maintain level flight. Modern drives are considerably more reliable than their predecessors in this regard, but extreme manoeuvres can still cause drive failures occasionally.\n\n");} else {return ""}},function(){if(player.ship.hasHyperspaceMotor) { return "If you are out of fuel";} else {return "As your ship does not have a witchdrive fitted"}}]},
{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
this.$mfdOn = false;
this.$mfdMode = 0;
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) % 5;
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) // next chapter
{
this.$mfdOffset = 0;
this.$mfdChapter--;
if (this.$mfdChapter < 0) {
this.$mfdChapter = this.$contents.length-1;
}
}
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 "---image unavailable---";
}
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);
} |