oolite/Resources/Scripts/oolite-nova-mission.js

420 lines
10 KiB
JavaScript

/*
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._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.275 && current > this._flareTarget)
{
removeFrameCallback(this._flareCallback);
delete this._flareCallback;
}
else if (this._flareTarget < 0.275 && 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",
screenID: "oolite-nova-briefing"
},
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",
screenID: "oolite-nova-hero"
});
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",
screenID: "oolite-nova-disappointed"
});
this._endTheMission();
}
else if (missionVariables.nova === "NOVA_ESCAPE_OTHER")
{
mission.runScreen({
titleKey: "oolite_nova_title",
messageKey: "oolite_nova_ignored",
background: "solar.png",
screenID: "oolite-nova-ignored"
});
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",
screenID: "oolite-nova-coward"
});
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;
system.info.sun_radius = this._novaRadius;
system.info.corona_flare = 0.3;
system.info.corona_hues = 0.05;
delete this.willGoNova;
delete this._novaRadius;
// 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;
this._novaRadius = system.sun.radius + 600000;
player.consoleMessage(expandDescription("[danger-fuel-leak]"), 4.5);
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);
if (system.info.corona_flare < 0.15) {
system.info.corona_flare = 0.15;
}
/* 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);
}
}
};