/* oolite-nova-mission.js Script for nova mission. Oolite Copyright © 2004-2013 Giles C Williams and contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*jslint white: true, undef: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */ /*global Timer, expandDescription, galaxyNumber, guiScreen, mission, missionVariables, player, system*/ "use strict"; this.name = "oolite-nova"; this.author = "Eric Walch, Jens Ayton, Kaks"; this.copyright = "© 2008-2013 the Oolite team."; this.version = "1.79"; this._endTheMission = function () { missionVariables.nova = "NOVA_HERO"; // even if not a hero, other scripts expect this string at mission end. mission.setInstructions(null); this._cleanUp(); }; this._cleanUp = function () { // mission is over, we don't need most of the event handlers. // this.shipExitedWitchspace is still needed after the nova mission. delete this.shipWillEnterWitchspace; delete this.shipWillExitWitchspace; delete this.systemWillPopulate; delete this.missionScreenOpportunity; delete this.shipLaunchedEscapePod; delete this.shipLaunchedFromStation; }; // used when player enters nova system during nova mission. this._sendShipsAwayForMission = function () { if (missionVariables.nova !== "TWO_HRS_TO_ZERO") { this.novaMissionTimer.stop(); } else { system.sendAllShipsAway(); if (!this.buoyLoaded) { this.witchBuoy = system.shipsWithPrimaryRole("buoy-witchpoint")[0]; this.buoyLoaded = true; } if (this.witchBuoy && this.witchBuoy.isValid) { this.witchBuoy.commsMessage(expandDescription("[oolite-nova-distress-call]")); } } }; // used when player enters nova system after nova mission. this._sendShipsAway = function () { if (!system.sun.hasGoneNova) { this.novaTimer.stop(); return; } else { system.sendAllShipsAway(); } }; // Destroy all stations (and carriers) in the system. If we just blow up the // main one, the player can eject, be rescued and buy fuel without triggering // the escape pod failure state. this._blowUpAllStations = function () { system.filteredEntities(this, function (entity) { if (entity.isStation) { entity.explode(); } }); }; this._flareUp = function () { system.info.corona_hues = 1; // This flare up (0.3 to 0.5 flare) will last between 10 and 30 seconds this._flareTarget = 0.3 + Math.random() * 0.2; this._flareCallback = addFrameCallback(this._flareTransition.bind(this)); this._flareChange(this._flareDown, Math.random() * 20 + 10); }; this._flareDown = function () { system.info.corona_hues = 0.8; // This quiet moment (0.1 to 0.25 flare) will last between 30 seconds and 2 minutes this._flareTarget = 0.1 + Math.random() * 0.15; this._flareCallback = addFrameCallback(this._flareTransition.bind(this)); this._flareChange(this._flareUp, Math.random() * 90 + 30); }; this._flareChange = function (callFunc, callDelay) { this.flareTimer.stop(); delete this.flareTimer; this.flareTimer = new Timer(this, callFunc, callDelay); }; this._flareTransition = function(delta) { var current = system.info.corona_flare; if (current < this._flareTarget) { current += delta/10; } else { current -= delta/10; } system.info.corona_flare = current; if (this._flareTarget > 0.375 && current > this._flareTarget) { removeFrameCallback(this._flareCallback); delete this._flareCallback; } else if (this._flareTarget < 0.375 && current < this._flareTarget) { removeFrameCallback(this._flareCallback); delete this._flareCallback; } } /**** Event handlers ****/ this.startUp = function () { // Remove all event handlers once the mission is over. if (missionVariables.nova === "NOVA_HERO") { this._cleanUp(); } delete this.startUp; }; this.missionScreenOpportunity = function () { if (!player.ship.docked) { return; } function choiceEvaluation(choice) { if (choice === "YES") { player.ship.useSpecialCargo(expandDescription("[oolite-nova-refugees]")); mission.setInstructionsKey("oolite_nova_info"); missionVariables.nova = "NOVA_ESCAPE_HERO"; player.ship.launch(); this._blowUpAllStations(); system.sun.goNova(30); } else { // choice == "NO", or null when player launched without making a choice. missionVariables.nova = "NOVA_ESCAPE_COWARD"; player.commsMessage(expandDescription("[oolite-nova-coward]"), 4.5); system.sun.goNova(9); // barely enough time to jump out of the system. } missionVariables.novacount = null; } if (player.ship.dockedStation.isMainStation) { if (galaxyNumber === 3) { if (!missionVariables.nova && !missionVariables.novacount) { missionVariables.novacount = 0; } if (missionVariables.nova === "TWO_HRS_TO_ZERO") { mission.runScreen({ titleKey: "oolite_nova_title", messageKey: "oolite_nova_brief", background: "solar.png", choicesKey: "oolite_nova_yesno" }, choiceEvaluation); this.novaMissionTimer.stop(); } } if (galaxyNumber === 3 || galaxyNumber === 4) { if (missionVariables.nova === "NOVA_ESCAPED_SYSTEM") { player.ship.removeAllCargo(); mission.runScreen({ titleKey: "oolite_nova_title", messageKey: "oolite_nova_hero", background: "solar.png" }); player.ship.manifest["gem-stones"] += 100; this._endTheMission(); } else if (missionVariables.nova === "NOVA_ESCAPE_POD") { player.ship.removeAllCargo(); // can only be done while docked. mission.runScreen( { titleKey: "oolite_nova_title", messageKey: "oolite_nova_disappointed", background: "solar.png" }); this._endTheMission(); } else if (missionVariables.nova === "NOVA_ESCAPE_OTHER") { mission.runScreen({ titleKey: "oolite_nova_title", messageKey: "oolite_nova_ignored", background: "solar.png" }); this._endTheMission(); } else if (missionVariables.nova === "NOVA_ESCAPE_COWARD" && !system.sun.isGoingNova && !system.sun.hasGoneNova) { player.decreaseContractReputation(); player.decreasePassengerReputation(); mission.runScreen({ titleKey: "oolite_nova_title", messageKey: "oolite_nova_disappointed", background: "solar.png" }); this._endTheMission(); } } } else if (missionVariables.nova === "TWO_HRS_TO_ZERO") { // this is the the nova system, but not the main station. player.ship.launch(); player.commsMessage(expandDescription("[oolite-nova-visit-main]")); } }; this.shipLaunchedEscapePod = function () { if (missionVariables.nova === "NOVA_ESCAPED_SYSTEM") { missionVariables.nova = "NOVA_ESCAPE_POD"; } }; this.shipWillEnterWitchspace = function () { if (this.willGoNova) { system.info.sun_gone_nova = true; delete this.willGoNova; // did the player leave the nova system without docking at the main station? if (missionVariables.nova === "TWO_HRS_TO_ZERO") { missionVariables.nova = "NOVA_ESCAPE_OTHER"; } } }; this.shipWillExitWitchspace = function () { if (missionVariables.nova === "NOVA_ESCAPE_HERO") { missionVariables.nova = "NOVA_ESCAPED_SYSTEM"; } else if (missionVariables.nova === "TWO_HRS_TO_ZERO") { // the populator has started the nova mission player.ship.fuelLeakRate = 25; this.willGoNova = true; player.consoleMessage(expandDescription("[danger-fuel-leak]"), 4.5); system.info.market = "none"; this.buoyLoaded = false; // w-bouy is not in system yet. if (this.novaMissionTimer) { this.novaMissionTimer.start(); } else { this.novaMissionTimer = new Timer(this, this._sendShipsAwayForMission, 5, 30); } } }; this.systemWillPopulate = function() // call this as soon as possible so other scripts can see it will go nova. { // make sure we don't increment the count when reloading a savegame if (!missionVariables.nova && galaxyNumber === 3 && player.ship.status != "STATUS_DOCKED") { if (missionVariables.novacount !== null) // " !== undefined" always returns true for missionVariables! { missionVariables.novacount++; } if (player.ship.equipmentStatus("EQ_GAL_DRIVE") === "EQUIPMENT_OK" && missionVariables.novacount > 3 && !missionVariables.nova && !system.isInterstellarSpace) { missionVariables.nova = "TWO_HRS_TO_ZERO"; system.sun.goNova(7200); /* the main populator script might have run first. If so, remove * the ships it added. If it runs after, it'll notice the * impending nova and not add these lines in the first place */ var populator = system.populatorSettings; var keys = Object.keys(populator); var key; while (key = keys.shift()) { if (key.match(/^oolite-/) && populator[key].priority > 20) { // remove it system.setPopulator(key,null); } } } } } this.shipLaunchedFromStation = function () { if (system.sun && (system.sun.isGoingNova || system.sun.hasGoneNova) && missionVariables.nova === "NOVA_ESCAPE_COWARD") { this._blowUpAllStations(); } }; this.shipExitedWitchspace = function () { if (system.sun) { if (this.flareTimer) { this.flareTimer.stop(); delete this.flareTimer; } if (this._flareCallback) { removeFrameCallback(this._flareCallback); delete this._flareCallback; } if (system.sun.isGoingNova || system.sun.hasGoneNova) { if (this.novaTimer) { this.novaTimer.start(); } else { this.novaTimer = new Timer(this, this._sendShipsAway, 5, 60); } } if (system.sun.isGoingNova) { // The first flare up will begin in between 30 seconds and 1 minute. this.flareTimer = new Timer(this, this._flareUp, Math.random() * 30 + 30); } } };