Back to Index Page generated: Dec 20, 2024, 7:22:10 AM

Expansion Rescue Stations

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description The RRS Group is the leading specialist for official retrieval and rescue work. This OXP adds their stations and ships to some safe systems, where Commanders with a suitable reputation may find a variety of employment offers. The RRS Group is the leading specialist for official retrieval and rescue work. This OXP adds their stations and ships to some safe systems, where Commanders with a suitable reputation may find a variety of employment offers.
Identifier oolite.oxp.spara.rescue_stations oolite.oxp.spara.rescue_stations
Title Rescue Stations Rescue Stations
Category Systems Systems
Author cim, spara cim, spara
Version 1.5.4 1.5.4
Tags missions, stations missions, stations
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/RRS_Group n/a
Download URL https://wiki.alioth.net/img_auth.php/0/05/Rescue_stations_1.5.4.oxz n/a
License CC-BY-NC-SA 3.0 CC-BY-NC-SA 3.0
File Size n/a
Upload date 1610873215

Documentation

Also read http://wiki.alioth.net/index.php/Rescue%20Stations

rescue_stations_readme_and_licence.txt

Rescue Stations OXP ver 1.5.4 (20.6.2017)

Author: original by cim, update by spara

_Description_

This oxp is an updated version of Rescue Stations OXP by cim. 

* New model and texture for RRS Arafura
* New Sidewinder model, texture and scripting
* Hires texture && BGS tunnel texture for RRS station
* Hires texture && BGS tunnel texture for RRS HQ station
* References Griff's Wolf 2 and ships from Staer9 shipset and sb-faves shipset.
* New solar probe texture
* Integration for Skilled NPCs oxp
* Added backgrounds to all mission screens without models
* Added station interface (f4)
* Station validator support
* Custom rrs buoy for hq and waystation
* Ship naming retouched, random shipnames integration
	* Civilian arafuras named with random ship names oxp
	* Rrs arafuras & escorts named with wing names
	* Rrs defenders named with random ship names
	* Mission ships named with random shipnames oxp when appropriate
* Mining Posts with vast asteroid fiels added to selected systems
* Many, many tweaks and fixes

_Install_

Install the OXP by copying rescue_stations.oxp to AddOns-folder

_Credits_

* Bug fixes by phkb
* Arafura re-textured from Puma Clipper by Dertien. Model tweaked by Keeper. Shader magic by Keeper.
* RRS Waystation shader magic by Keeper
* Eva probe model tweaked by Keeper.
* Sidewinder re-textured from Sidewinder by Dertien.
* Rock texure for RrS HQ Station by Griff
* Mining Outpost is made from ADCK's rock hermit.

------

This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/

Equipment

Name Visible Cost [deci-credits] Tech-Level
Rescue EVA craft yes 100 1+
Advanced Navigation Array (RRS discount) yes 10125 7+
Advanced Space Compass (RRS discount) yes 2925 8+
Special cargo holder no 0 1+
Special cargo holder no 0 1+
Special cargo holder no 0 1+
Special cargo holder no 0 1+
Special cargo holder no 0 1+
Docking Computer (RRS discount) yes 6750 6+
Escort Targeting System yes 15000 13+
Escort Targeting System (RRS discount) yes 6000 6+
Escort Targeting System yes 15000 6+
Flight Formation Autopilot yes 5000 7+
Flight Formation Autopilot (RRS discount) yes 2000 7+
Complimentary refuelling yes 25 1+
RRS Equipment Package yes 5000 1+
Heat shielding (RRS discount) yes 6750 5+
Scanner Targeting Enhancement yes 4500 6+
Scanner Targeting Enhancement (RRS discount) yes 2025 6+
Fuel Scoops (RRS discount) yes 2360 6+
RRS Service yes 2500 1+
RRS Solar laboratory yes 400 4+

Ships

Name
Arafura
arafura_ind
arafura_player
arafura_s1
arafura_s1b
arafura_s5a
rescue_blackbox
rescue_blackbox_generic
Black Box
rescue_freighter_PAG_monitor
rescue_freighter_PAG_monitor2
rescue_freighter_Z_Porcupine
rescue_freighter_Z_Python_Courier
rescue_freighter_anaconda
rescue_freighter_aquatics_conger
rescue_freighter_aquatics_manOWar
rescue_freighter_blueracer
rescue_freighter_boa
rescue_freighter_boa-mk2
rescue_freighter_boaclipper
rescue_freighter_grs_guanako
rescue_freighter_oohauler-player
rescue_freighter_pelamis
rescue_freighter_python
rescue_freighter_python-clipper
rescue_freighter_python-cruiser
Rescue EVA Pod
RRS Waystation
rescue_target_PAG_monitor
rescue_target_PAG_monitor2
rescue_target_Z_Porcupine
rescue_target_Z_Python_Courier
rescue_target_anaconda
rescue_target_aquatics_conger
rescue_target_aquatics_manOWar
rescue_target_blueracer
rescue_target_boa
rescue_target_boa-mk2
rescue_target_boaclipper
rescue_target_grs_guanako
rescue_target_oohauler-player
rescue_target_pelamis
rescue_target_python
rescue_target_python-clipper
rescue_target_python-cruiser
rrs_aphid
rrs_asp
rrs_asp1
rrs_asteroid_sidewinder_inactive
rrs_astroguard_commies
rrs_astroguard_rockhermit
rrs_astromine_commies
Astromine Penal Colony
rrs_astrominer_commies
rrs_astrominer_rockhermit
rrs_autopilot_screen
rrs_box
rrs_chuckwalla
rrs_cobra3
rrs_cobracourier
rrs_cobrarapier
rrs_delta
RRS Dock
RRS Dock
rrs_dragon-an
rrs_dragon-m
rrs_dragon-se
rrs_drake
rrs_drakemk2
rrs_excalibur
rrs_gecko
rrs_gemini
RRS Headquarters
rrs_headquarters_bay
rrs_headquarters_bay_dock
rrs_headquarters_bay_ff
rrs_headquarters_construct
rrs_hq_buoy
rrs_iguana
rrs_koneko
rrs_llama
rrs_mamba
rrs_manta
rrs_moccasin
rrs_outrider
rrs_paladin
rrs_plague_mine
rrs_redracer
rrs_salamander
rrs_shark
rrs_sidewinder
Slaver Base
rrs_slaver_pod
RRS Solar Laboratory
rrs_taipan
rrs_waystation_pointer
Mining Outpost
Hermit Dock
Sidewinder
Sidewinder
rrsfl_rescue_freighter_monitor
rrsfl_rescue_freighter_monitor2
rrsfl_rescue_freighter_python-cruiser
rrsfl_rescue_target_monitor
rrsfl_rescue_target_monitor2
rrsfl_rescue_target_python-cruiser
rrsfl_rrs_aphid
rrsfl_rrs_cobrarapier
rrsfl_rrs_iguana
rrsfl_rrs_salamander
rrsfl_rrsl_monitor
rrsfl_rrsl_monitor2
rrsfl_rrsl_pcc
rrsfl_rsvh_c3r
rrsfl_rsvh_iguana
rrsfl_rsvh_salamander
rrsfl_rsvh_wolf2
rrsl_monitor
rrsl_monitor2
rrsl_pcc
rrsl_porcupine
rrsl_python
rsvh_adder
rsvh_adder2
rsvh_asp
rsvh_asp1
rsvh_aspexp
rsvh_barracuda
rsvh_c3c
rsvh_c3com
rsvh_c3r
rsvh_chuckwalla
rsvh_cobra1
rsvh_cobra3
rsvh_dragon-an
rsvh_dragon-m
rsvh_drake2
rsvh_eel
rsvh_excalibur
rsvh_fdl
rsvh_icarus
rsvh_iguana
rsvh_koneko
rsvh_krait
rsvh_manta
rsvh_mosquito
rsvh_mossport
rsvh_outrider
rsvh_paladin
rsvh_redracer
rsvh_salamander
rsvh_shark
rsvh_sidewinder
rsvh_taipan
rsvh_urutu3
rsvh_urutu4
rsvh_wolf2

Models

This expansion declares no models.

Scripts

Path
Scripts/rescue-station.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0"; 
this.name      = "RRS Rescue Station";
this.description = "Rescue Station script";

//removed launch port workaround -spara-

this.lighttime = 0;
this.lighttimer = undefined;

this.missionLaunch = function() {
		var arafura = this.ship.launchShipWithRole("rrs-arafura");
		if (Math.random() < 0.5) {
// go for planet or hyperspace out at random
				arafura.switchAI("exitingTraderAI.plist");
		}
}

this.otherShipDocked = function(whom) {
		this.lighttime = clock.seconds;
}

this.checkLights = function checkLights() {
		if (this.lighttime + 10 > clock.seconds) {
				if (this.lighttimer && this.lighttimer.isRunning) this.lighttimer.stop();
				this.lighttimer = new Timer(this,this.checkLights,10);
				return;
		}
		if (player.dockingClearanceStatus != "DOCKING_CLEARANCE_STATUS_NONE") {
				if (this.lighttimer && this.lighttimer.isRunning) this.lighttimer.stop();
				this.lighttimer = new Timer(this,this.checkLights,10);
				return;
		}
		// then no-one has launched or docked recently, and the player
		// isn't waiting, and we only get this far if there's nothing in
		// the queue
		this.ship.reactToAIMessage("DOCKING_LIGHTS_OFF");
}

this.shipDied = function(whom, why) {
	if (this.lighttimer && this.lighttimer.isRunning) this.lighttimer.stop()
}

this.shipRemoved = function(suppress) {
	if (this.lighttimer && this.lighttimer.isRunning) this.lighttimer.stop()
}
Scripts/rescue_ambience.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Ambience";
this.description = "Adds occasional RRS-group flavour to this Ooniverse outside of (and around) missions";

//Add 6a mining bases to suitable systems -spara-
//handle generic blackboxes -spara-

this.timer1 = undefined; // plague 
this.timer2 = undefined; // no entry

/* One-off actions */

this.startUp = function() {
		this.updatePlanetInfo();

// Compatibility with other scripts that change system details.
// Specifically, leave Lezaer to us.
// System Redux
		if (worldScripts["System Redux"]) {
				if (worldScripts["System Redux"].startUp) {
						// make sure this has started first
						worldScripts["System Redux"].startUp();
				}
				worldScripts["System Redux"].changeSystems([[],[],[5],[],[],[],[],[]]);
		}
// System Demux
		if (worldScripts["System Demux"]) {
				if (!worldScripts["System Demux"].firstLaunch) {
						worldScripts["System Demux"].startUp();
				}
				worldScripts["System Demux"].system_info[517] = 0x0000; // 256*2 + 5
		}
// Deep Horizons Systems
		if (worldScripts["SystemRedux2API"]) {
				worldScripts["SystemRedux2API"].excludeSystem(2,5,{TextureMP:"true", AddPlanets:"true", AddMoons:"true", TxtPlanets:"true", TxtMoons:"true", ReduSun:"false"});
		}
		if (worldScripts["Deep Horizon - Systems API"]) {
			worldScripts["Deep Horizon - Systems API"].excludeSystem(2,5,{TextureMP:"true", AddPlanets:"true", AddMoons:"true", TxtPlanets:"true", TxtMoons:"true", ReduSun:"true"});	
		}

}

this.playerEnteredNewGalaxy = function(gal) {
		this.updatePlanetInfo();
}

this.updatePlanetInfo = function() {
		var hqsysid = worldScripts["Rescue Stations"].systemWithRescueHQStation();
		
		var cdesc = System.infoForSystem(galaxyNumber,hqsysid).description;
		if (cdesc.indexOf("RRS") == -1) {
				System.infoForSystem(galaxyNumber,hqsysid).description = cdesc+" RRS Galactic Headquarters are in this system.";
		}
}


/* Each-system actions */


this.addAmbience = function() {
		if (system.isInterstellarSpace) {
				return;
		}
		// Plague Systems from 6a
		if (this.plagueActive()) {
				this.plagueSystem();
		}

		// System barring from diplomatic incidents
		if (missionVariables.rescuestation_noentry) {
				this.barredFromSystem();
		}
		// //// To avoid confusion the following should only appear outside missions
		if (!worldScripts["Rescue Stations"].missionActive()) {
				// potentially add a few generic black boxes to the space lanes
				this.blackBox();

				// asteroid fields from 1a and 3
				// because they should be there even if there isn't anything in them ;)				
				this.asteroidField();
		}
}

this.plagueActive = function() {
		if (system.info.description.indexOf("disease") == -1) {
				return false; // not a plague system
		}
		var pstart = system.ID;
		var plength = 128-(system.info.techlevel*8);
		var day = clock.days % 384;
		return (day >= pstart && day <= pstart+plength);
}

this.plagueSystem = function() {
// slight delay to stop message being lost
		this.timer1 = new Timer(this,this.plagueSystemAux,6);
}

this.plagueSystemAux = function() {
		var beacon = system.shipsWithRole("buoy-witchpoint");
		if (beacon.length > 0) {
				beacon[0].commsMessage("[rescue_plague_system]");
		}
}

this.asteroidField = function() {
		if (Math.random() < 0.05) {
				this.asteroidField1(); // scenario 3/3a style
		} else if (Math.random() < 0.05) {
				this.asteroidField2(); // scenario 1a style
		}
}

this.asteroidField1 = function() {
		var fieldcentre = Vector3D(0,0,0.2+(Math.random()*0.3)).fromCoordinateSystem("wsu");
		fieldcentre.add(Vector3D.random(20E3));
		
		var asteroids = 25+Math.floor(Math.random()*100);
		var fieldradius = 1E3*(20+Math.random()*50);
		for (var i=0;i<asteroids;i++) {
				var apos = fieldcentre.add(Vector3D.randomDirectionAndLength(fieldradius));
				system.addShips("asteroid",1,apos,1E3);
		}
}

this.asteroidField2 = function() {
		var dpos = Vector3D.randomDirection().multiply(60E3);
		var cpos = dpos.add(Vector3D.random(5E3));
		var asteroids = 50;
		var fieldradius = 30E3;
		for (var i=0;i<asteroids;i++) {
				var apos = cpos.add(Vector3D.randomDirectionAndLength(fieldradius));
				var aster = system.addShips("asteroid",1,apos,1E3);

				if (aster[0].position.distanceTo(dpos) > 20E3 && Math.random() < 0.5) {
						var vel = dpos.subtract(aster[0].position);
						
						aster[0].velocity = vel.multiply((2+(Math.random()*9))/(5E3));
				}
		}

}

this.blackBox = function() {
		if (Math.random() < 0.5) {
				var bb = system.addShipsToRoute("rescue_blackbox_generic",1,0.1+Math.random()*0.8,"wp");
				bb[0].velocity = Vector3D.randomDirection();
		}
// less on the quieter routes; too easy
		if (Math.random() < 0.1) {
				var bb = system.addShipsToRoute("rescue_blackbox_generic",1,0.1+Math.random()*0.7,"ws");
				bb[0].velocity = Vector3D.randomDirection();
		}
		if (Math.random() < 0.1) {
				var bb = system.addShipsToRoute("rescue_blackbox_generic",1,0.1+Math.random()*0.7,"ps");
				bb[0].velocity = Vector3D.randomDirection();
		}

}

this.barredFromSystem = function() {
		if (missionVariables.rescuestation_noentry == system.ID) {
				if (missionVariables.rescuestation_noentrytime > clock.days) {
						// nothing; something odd has happened
						delete missionVariables.rescuestation_noentry;
						delete missionVariables.rescuestation_noentrytime;
				} else {
						var chance = clock.days-missionVariables.rescuestation_noentrytime;
						if (chance < Math.random()*100) {
								this.timer2 = new Timer(this,this.barredFromSystemAux,6);
						} else {
								delete missionVariables.rescuestation_noentry;
								delete missionVariables.rescuestation_noentrytime;
								// got away with it.
						}
				}
		} else if (missionVariables.rescuestation_noentrytime + 100 < clock.days) {
				delete missionVariables.rescuestation_noentry;
				delete missionVariables.rescuestation_noentrytime;
				// lapsed, stop checking
		}
}

this.barredFromSystemAux = function() {
		var beacon = system.shipsWithRole("buoy-witchpoint");
		if (beacon.length > 0) {
				beacon[0].commsMessage("[rescue_barred_system]");
		}
		this.timer2 = new Timer(this,this.barredFromSystemBaux,40);
}

this.barredFromSystemBaux = function() {
		if (missionVariables.rescuestation_noentry == system.ID) {
				// if not, they jumped out in time
				var beacon = system.shipsWithRole("buoy-witchpoint");
				if (beacon.length > 0) {
						beacon[0].commsMessage("[rescue_barred_system2]");
				}
				player.bounty += 20;
		}
}

//generic blackboxes handling

this.$blackboxes = new Array();

//notify player that a black box has been scooped
//add scooped black box to an array
this.shipScoopedOther = function(whom) {
	if (whom.primaryRole === "rescue_blackbox_generic") {
		player.consoleMessage("Return the black box to any station for a reward.", 5);
		this.$blackboxes.push(whom);
	}
}

//cash the loot
this.shipWillDockWithStation = function(station) {
	for (var i = 0; i < this.$blackboxes.length; i++) {
		if (this.$blackboxes[i].status === "STATUS_IN_HOLD") {
			var payment = 25+Math.floor(50*Math.random());
			var message = "For recovering the black box of the [rescue_random_shipname], insurance pays "+payment+" Cr.";
			missionVariables.rescuestation_reputation++;
			player.credits += payment;
			player.addMessageToArrivalReport(expandDescription(message));
			if (manifest.machinery > 0) manifest.machinery--;
		}
	}
	this.$blackboxes = new Array();
}
Scripts/rescue_autopilot.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Autopilot";
this.description = "The world script for the RRS escort autopilot";

this.hopsize = 5E3;
this.callback = undefined;
this.screen = undefined;

this.findAnything = function(entity) {
		return !entity.hasRole("alloy"); // anything but the reference object
}

this.findDangerous = function(entity) {
// we're being quite conservative, so dangerous *to who* isn't being considered.
		return (entity.isShip && (entity.hasHostileTarget || entity.isWeapon || entity.isPirate || entity.isThargoid)) || entity.isStation;
}

this.findDangerous2 = function(entity) {
// things that are only dangerous to offenders
		return (entity.isShip && (entity.isPolice || entity.scanClass == "CLASS_MILITARY" || entity.primaryRole == "hunter"));
}


this.autopilotStep = function(ship) {
		if (!ship.isValid) {
				return;
		}
		if (!ship.script.autopilotwilling) {
				return;
		}
		
		// Firstly, check if we're there yet.
		if (ship.savedCoordinates.distanceTo(ship.position) < 20E3) {
				
				ship.reactToAIMessage("DESTINATION_NEAR");
				return;
		}

    // then check if we can safely make the next hop.
		var nextjump = ship.vectorForward.multiply(5E3);
		var nexthoppos = ship.position.add(nextjump);
		var alloy = system.addShips("alloy",1,nexthoppos,1)[0];
		if (system.filteredEntities(this,findAnything,alloy,hopsize/2).length > 0) {
				ship.reactToAIMessage("OBSTACLES_NEAR");
				alloy.remove(true);
				return;
		}
		alloy.remove(true);

		// then check if we can safely do so
		if (system.filteredEntities(this,findDangerous,ship,25600).length > 0) {
				ship.reactToAIMessage("HOSTILES_NEAR");
				return;
		}

		if (ship.bounty > 0 || player.bounty > 0) {
				if (system.filteredEntities(this,findDangerous2,ship,25600).length > 0) {
						ship.reactToAIMessage("HOSTILES_NEAR");
						return;
				}
		}

		// okay, make the next hop

		ship.position = ship.position.add(nextjump);
		player.ship.position = player.ship.position.add(nextjump);
		player.ship.orientation = ship.orientation;
		player.ship.velocity = ship.velocity;
		if (ship.escorts) {
				for (var i=0;i<ship.escorts.length;i++) {
						ship.escorts[i].position = ship.escorts[i].position.add(nextjump);
				}
		}
		var extras = system.shipsWithRole("rrs-flightcomp-aux",ship,15E3);
		for (var i=0;i<extras.length;i++) {
				extras[i].position = extras[i].position.add(nextjump);
		}

		var adjustment = hopsize/ship.speed;

		clock.addSeconds(adjustment);
		
}


Scripts/rescue_blackbox.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Generic Black Box";
this.description = "(generic) Black Box script";

this.shipSpawned = function() {
		if (worldScripts["Rescue Stations"].missionActive()) {
				this.ship.setScript("rescue_scenario_"+missionVariables.rescuestation_scenario+"_blackbox.js");
				this.ship.switchAI("rescue_scenario_"+missionVariables.rescuestation_scenario+"_blackboxAI.plist");

		}
}
Scripts/rescue_derelict.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Generic Derelict";
this.description = "(generic) Derelict script";

this.shipSpawned = function() {
		if (worldScripts["Rescue Stations"].missionActive()) {
				this.ship.setScript("rescue_scenario_"+missionVariables.rescuestation_scenario+"_derelict.js");
				this.ship.switchAI("rescue_scenario_"+missionVariables.rescuestation_scenario+"_derelictAI.plist");
		}
}
Scripts/rescue_evaprobe.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Moray EVA";
this.description = "(generic) AI for the Moray EVA 'missile'";

this.abandonDock = function() {
		this.commsMessage("Unable to dock with derelict - abort mission!");
		missionVariables.rescuestation_stage = 0;
		this.owner.sendAIMessage("ABORT_MISSION_EVA");
		this.ship.remove(true);
}

this.derelictDock = function() {
		this.ship.target.sendAIMessage("EVA_DOCKED");
		this.ship.remove(true);
}

this.shipCollided = function(other) {
		this.ship.target.sendAIMessage("EVA_DOCKED");
		this.ship.remove(true);
}

this.shipDied = function(other) {
		this.ship.target.sendAIMessage("EVA_DOCKED");
}
Scripts/rescue_leader.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Generic Rescue Leader";
this.description = "(generic) Rescue Leader script";

this.shipSpawned = function() {
		if (worldScripts["Rescue Stations"].missionActive()) {
				this.ship.setScript("rescue_scenario_"+missionVariables.rescuestation_scenario+"_leader.js");
				this.ship.switchAI("rescue_scenario_"+missionVariables.rescuestation_scenario+"_leaderAI.plist");
		}
}
Scripts/rescue_missions.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Stations"; 
this.description = "This script adds rescue stations and rescue missions. (main script for OXP)"; 

this.lastmissiongen = 0;
this.scenarios = new Array();
this.variantscenarios = new Array();
this.availablescenarios = new Array();
this.missionpointer = 0;
this.runonce = 0;
this.missionlog = new Object();

this.testmode = "";

this.startUp = function() {
		if (!missionVariables.rescuestation_stage) {
				// first run
				missionVariables.rescuestation_stage = 0;
		}
		if (!missionVariables.rescuestation_reputation) {
				// first run
				missionVariables.rescuestation_reputation = 0;
		}
		if (!missionVariables.rescuestation_prevreputation) {
				missionVariables.rescuestation_prevreputation = 0;
		}
		if (!missionVariables.rescuestation_firstconv) {
				// first run
				missionVariables.rescuestation_firstconv = 0;
		}
		if (!missionVariables.rescuestation_missionlog) {
				// first run
				missionVariables.rescuestation_missionlog = "";
		} else {
				var missionlogs = missionVariables.rescuestation_missionlog.split(";");
				for (var i=0;i<missionlogs.length;i++) {
						var missiondata = missionlogs[i].split("=");
						this.missionlog[missiondata[0]] = missiondata[1];
				}
				this.syncMissionLog();
		}

		this.lastmissiongen = clock.hours-1;
		
		this.tryAddingRescueStation(true);

		delete this.startUp;
}

this.startUpComplete = function() {
	
	if (player.ship.dockedStation.hasRole("rescue_station") && missionVariables.rrs_available_scenarios) {
		this.availablescenarios_save = JSON.parse(missionVariables.rrs_available_scenarios);
		this.lastmissiongen = clock.hours;
		this.fillMissionBoard();
	}
}

this.registerScenario = function(sckey) { // register basic scenarios
		this.scenarios.push(sckey);

// transfer old-style variables
		if (missionVariables["rescuestation_scenario_"+sckey+"_complete"]) {
				this.missionlog[sckey+"_complete"] = missionVariables["rescuestation_scenario_"+sckey+"_complete"];
 		}
		delete missionVariables["rescuestation_scenario_"+sckey+"_complete"];

}

this.registerVariant = function(origkey,sckey) { // register variant scenarios
		var vdesc = new Array();
		vdesc.push(origkey);
		vdesc.push(sckey);

		this.variantscenarios.push(vdesc);

// transfer old-style variables
		if (missionVariables["rescuestation_scenario_"+sckey+"_complete"]) {
				this.missionlog[sckey+"_complete"] = missionVariables["rescuestation_scenario_"+sckey+"_complete"];
		}
		delete missionVariables["rescuestation_scenario_"+sckey+"_complete"];

}

this.syncMissionLog = function() {
		var mlogs = new Array();
		for (key in this.missionlog) {
				mlogs.push(key+"="+this.missionlog[key]); 
		}
		missionVariables.rescuestation_missionlog = mlogs.join(";");
}

this.scenariosWon = function(sckey) {
		if (this.missionlog[sckey+"_complete"]) {
				return this.missionlog[sckey+"_complete"];
		} else {
				return 0;
		}
}

this.scenariosLost = function(sckey) {
		if (this.missionlog[sckey+"_failed"]) {
				return this.missionlog[sckey+"_failed"];
		} else {
				return 0;
		}
}

this.scenariosTried = function(sckey) {
		return this.scenariosWon(sckey)+this.scenariosLost(sckey);
}

/* Event handlers */
this.playerWillSaveGame = function() {
	this.syncMissionLog();
	if (player.ship.dockedStation.hasRole("rescue_station") && this.availablescenarios_save) {
		missionVariables.rrs_available_scenarios = JSON.stringify(this.availablescenarios_save);
	}
}

this.shipWillExitWitchspace = function() {
	
		this.tryAddingRescueStation(false);

		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipWillExitWitchspace) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipWillExitWitchspace();
		}
// reputation won't appear until at least one mission at least considered
		if (missionVariables.rescuestation_reputation > 400) { // cap at 400
				missionVariables.rescuestation_reputation = 400;
				if (!this.missionActive()) {
						this.setMissionDetails(this.reputationString());
				}
		} else if (missionVariables.rescuestation_reputation > 0) {
				for (var i=0;i<missionVariables.rescuestation_reputation;i+=20) {
						// lose one rank point for every 20 owned while not on a mission
						// need to do more difficult missions at higher ranks to get a promotion
						if (!this.missionActive()) {
								if (missionVariables.rescuestation_reputation == 10 ||
										missionVariables.rescuestation_reputation == 20 ||
										missionVariables.rescuestation_reputation == 40 ||
										missionVariables.rescuestation_reputation == 80 ||
										missionVariables.rescuestation_reputation == 160 ||
										missionVariables.rescuestation_reputation == 320) {
										// nothing: general decay won't reduce rank
								} else {
										missionVariables.rescuestation_reputation--;
								}
						} // no general decay if on a mission
						if (player.bounty > 0) {
								missionVariables.rescuestation_reputation--;
								if (player.bounty > 50) {
										missionVariables.rescuestation_reputation--;
								}
						}
				}
				if (!this.missionActive()) {
						this.setMissionDetails(this.reputationString());
				}
		} else if (missionVariables.rescuestation_reputation < 0 && player.bounty == 0) {
				missionVariables.rescuestation_reputation++;
				if (!this.missionActive()) {
						this.setMissionDetails(this.reputationString());
				}
		} else if (missionVariables.rescuestation_reputation > -30 && player.bounty >= 50) {
				missionVariables.rescuestation_reputation--; // fugitives can take a while to be trusted again
		}
}

this.shipExitedWitchspace = function () { 
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipExitedWitchspace) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipExitedWitchspace();
		}

}

this.shipWillLaunchFromStation = function (rstation) { 
		if (this.saveAnywhere()) {
				return; // ignore on Save-Anywhere usage
		}

		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipWillLaunchFromStation) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipWillLaunchFromStation(rstation);
		}
		//remove interface when launching
		player.ship.dockedStation.setInterface("rescue_station",null);
}

this.shipDockedWithStation = function(rstation) {
		if (this.saveAnywhere()) {
				return; // ignore on Save-Anywhere usage
		}
		this.missionpointer = 0; //reset bulletin pointer
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipDockedWithStation) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_shipDockedWithStation(rstation);
		}
		if (!this.missionActive() && rstation.hasRole("rescue_station"))
			this.fillMissionBoard();
}

this.guiScreenChanged = function(to, from) {
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_guiScreenChanged) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_guiScreenChanged(to, from);
		}
/*
		if (player.ship.docked && player.ship.dockedStation.hasRole("rescue_station") && guiScreen === "GUI_SCREEN_STATUS") {
				//add interface when there are missions.
		}
*/
}

this.solarLabReactionComplete = function () { 
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabReactionComplete) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabReactionComplete();
		}

}

this.solarLabCollected = function (scooper) { 
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabCollected) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabCollected(scooper);
		}

}

this.solarLabDeployed = function () { 
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabDeployed) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabDeployed();
		}

}


this.solarLabDestroyed = function () { 
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabDestroyed) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_solarLabDestroyed();
		}

}


this.missionScreenOpportunity = function() {
		if (this.saveAnywhere()) {
				return;
		}
/*		// TESTING
		systemlist = new Array();
		for (i=0;i<=255;i++) {
				si = System.infoForSystem(galaxyNumber,i);
				sr = this.rrsRandom(galaxyNumber,i);
				if ((si.government == 7 && sr < 0.75) || 
						(si.government == 6 && sr < 0.5) || 
						(si.government == 5 && sr < 0.25)) {
						systemlist.push(si.name);
				}
		}
		systemlist.sort();
		systemliststr = " "+systemlist.length+" : "+systemlist.join(", ");
		mission.runScreen ({title: "Local stations",
														message: systemliststr});
		log(this.name,"Gal"+galaxyNumber+":"+systemliststr);
		return; */
		
		if (player.ship.dockedStation.hasRole("rescue_station") && missionVariables.rescuestation_firstconv == 0) {
				missionVariables.rescuestation_firstconv = 1;
				mission.runScreen ({title: "Welcome to RRS",
														screenID: "rrs_mission",
														messageKey: "rescue_welcome_screen",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"
														});

				
		} 
		else if (player.ship.dockedStation.hasRole("rescue_station") && this.hasRankIncreased()) {
				mission.runScreen ({title: "Congratulations, Commander",
														screenID: "rrs_mission",
														messageKey: "rescue_promotion_screen_"+this.hasRankIncreased(),
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"
														});
				missionVariables.rescuestation_prevreputation = missionVariables.rescuestation_reputation;
		} else {

				if (missionVariables.rescuestation_stage > 0) {
						if (worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_missionScreenOpportunity) {
								worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_missionScreenOpportunity();
						}
				}
				
				 else if (this.availablescenarios.length > 0 && player.ship.dockedStation.hasRole("rescue_station")) {
						if (this.availablescenarios.length == 1) {
								var ckey = "rescue_mission_intro_choice_last";
						} else {
								var ckey = "rescue_mission_intro_choice";
						}

						if (this.missionpointer >= this.availablescenarios.length) {
								this.missionpointer = 0;
						}

						mission.runScreen ({title: "RRS Contracts ("+(this.missionpointer+1)+"/"+this.availablescenarios.length+")" ,
																messageKey: "rescue_scenario_"+this.availablescenarios[this.missionpointer]+"_synopsis",
																screenID: "rrs_mission",
																choicesKey: ckey,
																model: "rescue_station",
																background: "rrsfl_blank_bg.png",
																//exitScreen: "GUI_SCREEN_INTERFACES"
																},
															 this.examineMission);
						

				}
				
		}
}

this.playerEnteredNewGalaxy = function() {
		if (this.missionActive()) {
				this.failMission();
				player.consoleMessage("You have abandoned your RRS Group assignment",10);
		}
		delete missionVariables.rescuestation_noentry;
		delete missionVariables.rescuestation_noentrytime;
}

this.playerBoughtEquipment = function(equipment) {
		if (equipment == "EQ_RRS_FUEL") {
				player.ship.removeEquipment("EQ_RRS_FUEL");
				player.ship.fuel = 7;
		} else if (equipment == "EQ_RRS_SCOOPS") {
				player.ship.removeEquipment("EQ_RRS_SCOOPS");
				if (player.ship.canAwardEquipment("EQ_FUEL_SCOOPS")) {
						player.ship.awardEquipment("EQ_FUEL_SCOOPS");
				} else {
						player.consoleMessage("Sorry: your ship doesn't have anywhere we can fit fuel scoops.");
						player.credits += 472.5;
				}
		} else if (equipment == "EQ_RRS_SCANNER_SHOW_MISSILE_TARGET") {
				player.ship.removeEquipment("EQ_RRS_SCANNER_SHOW_MISSILE_TARGET");
				if (player.ship.canAwardEquipment("EQ_SCANNER_SHOW_MISSILE_TARGET")) {
						player.ship.awardEquipment("EQ_SCANNER_SHOW_MISSILE_TARGET");
				} else {
						player.consoleMessage("Sorry: your ship doesn't have anywhere we can fit a Scanner Targeting Enhancement.");
						player.credits += 900;
				}
		} else if (equipment == "EQ_RRS_SCANNER_SHOW_MISSILE_TARGET_DISCOUNT") {
				player.ship.removeEquipment("EQ_RRS_SCANNER_SHOW_MISSILE_TARGET_DISCOUNT");
				if (player.ship.canAwardEquipment("EQ_SCANNER_SHOW_MISSILE_TARGET")) {
						player.ship.awardEquipment("EQ_SCANNER_SHOW_MISSILE_TARGET");
				} else {
						player.consoleMessage("Sorry: your ship doesn't have anywhere we can fit a Scanner Targeting Enhancement.");
						player.credits += 405;
				}

		} else if (equipment == "EQ_RRS_DOCK_COMP") {
				player.ship.removeEquipment("EQ_RRS_DOCK_COMP");
				if (player.ship.canAwardEquipment("EQ_DOCK_COMP")) {
						player.ship.awardEquipment("EQ_DOCK_COMP");
				} else {
						player.consoleMessage("Sorry: your ship's systems are incompatible with the docking computer software.");
						player.credits += 1350;
				}
		} else if (equipment == "EQ_RRS_ASC") {
				player.ship.removeEquipment("EQ_RRS_ASC");
				player.ship.awardEquipment("EQ_ADVANCED_COMPASS");
		} else if (equipment == "EQ_RRS_ANA") {
				player.ship.removeEquipment("EQ_RRS_ANA");
				player.ship.awardEquipment("EQ_ADVANCED_NAVIGATIONAL_ARRAY");
		} else if (equipment == "EQ_RRS_HEAT_SHIELD") {
				player.ship.removeEquipment("EQ_RRS_HEAT_SHIELD");
				player.ship.awardEquipment("EQ_HEAT_SHIELD");
		} else if (equipment == "EQ_RRS_DOCK_COMP") {
				player.ship.removeEquipment("EQ_RRS_DOCK_COMP");
				player.ship.awardEquipment("EQ_DOCK_COMP");
		} else if (equipment == "EQ_RRS_FLIGHTFORM_DISCOUNT") {
				player.ship.removeEquipment("EQ_RRS_FLIGHTFORM_DISCOUNT");
				player.ship.awardEquipment("EQ_RRS_FLIGHTFORM");
		} else if (equipment == "EQ_RRS_ESCORT_TARGETING_SYSTEM_DISCOUNT") {
				player.ship.removeEquipment("EQ_RRS_ESCORT_TARGETING_SYSTEM_DISCOUNT");
				player.ship.awardEquipment("EQ_RRS_ESCORT_TARGETING_SYSTEM");
		} else if (equipment == "EQ_RRS_ESCORT_TARGETING_SYSTEM_WAYSTATION") {
				player.ship.removeEquipment("EQ_RRS_ESCORT_TARGETING_SYSTEM_WAYSTATION");
				player.ship.awardEquipment("EQ_RRS_ESCORT_TARGETING_SYSTEM");


		} else if (equipment == "EQ_RRS_SERVICE") {
				player.ship.removeEquipment("EQ_RRS_SERVICE");
				var repairable = ["EQ_FUEL_SCOOPS",
											"EQ_ECM",
											"EQ_ESCAPE_POD",									
											"EQ_ENERGY_UNIT",
											"EQ_DOCK_COMP",
											"EQ_GAL_DRIVE",
											"EQ_FUEL_INJECTION",
											"EQ_SCANNER_SHOW_MISSILE_TARGET",
											"EQ_MULTI_TARGET",
											"EQ_ADVANCED_COMPASS",
											"EQ_ADVANCED_NAVIGATIONAL_ARRAY",
											"EQ_TARGET_MEMORY",
											"EQ_HEAT_SHIELD",
											"EQ_WORMHOLE_SCANNER",
											"EQ_FRAME_BOUNTY_SCANNER",
											"EQ_ESCAPE_CAPSULE_LOCATOR",
											"EQ_PLANETFALL",
											"EQ_ROCKHERMIT_SCANNER",
											"EQ_AUTO_EJECT",
											"EQ_BREAKABLE_HUD_IFF_SCANNER",
											"EQ_BREAKABLE_SHIELD_FORE",
											"EQ_BREAKABLE_SHIELD_AFT",
											"EQ_BREAKABLE_TORUSDRIVE",
											"EQ_BREAKABLE_WITCHDRIVE",
											"EQ_FRAME_FUEL_COLLECTOR",
											"EQ_ELECTRONIC_THUMB",
											"EQ_RRS_FLIGHTFORM",
											"EQ_RRS_ESCORT_TARGETING_SYSTEM"
										 ];
				var repaired = 0;
				for (var i=0;i<repairable.length;i++) {
						var repair = repairable[i];
						if (player.ship.equipmentStatus(repair) == "EQUIPMENT_DAMAGED") {
								repaired++;
								player.ship.setEquipmentStatus(repair,"EQUIPMENT_OK");
						}
				}
				if (repaired > 0) {
						clock.addSeconds(86400);
				} else {
						player.consoleMessage("Your ship doesn't appear to have any damaged equipment that we can repair.");
						player.credits += 500;
				}
		} else if (equipment == "EQ_RRS_FULLEQUIP") {
				player.ship.removeEquipment("EQ_RRS_FULLEQUIP");
				var rrsequips = ["EQ_SCANNER_SHOW_MISSILE_TARGET","EQ_FUEL_SCOOPS","EQ_ADVANCED_COMPASS","EQ_ADVANCED_NAVIGATIONAL_ARRAY","EQ_HEAT_SHIELD","EQ_DOCK_COMP","EQ_RRS_FLIGHTFORM","EQ_RRS_ESCORT_TARGETING_SYSTEM"];
				var added = 0;
				for (var i=0;i<rrsequips.length;i++) {
						var equip = rrsequips[i];
						if (player.ship.canAwardEquipment(equip)) {
								player.ship.awardEquipment(equip);
								added++;
						}
				}
				if (added == 0) {
						player.consoleMessage("Your ship is already equipped to RRS standards.");
						player.credits += 1000;
				} else {
						clock.addSeconds(86400);
				}
		}

}

/* Mission selection functions */

this.fillMissionBoard = function () {
		if (this.lastmissiongen < clock.hours) { // stop people just launching and re-entering to reset missions
				this.missionpointer = 0;
				this.availablescenarios = new Array();
				this.availablescenarios_save = new Array();
				this.usedreplacements = new Array();
				this.variantscenarios.sort(function(a,b) { return Math.random()-0.5; }); // shuffle order so it isn't always the same variant being checked first

				if (this.testmode == "") {
						for (var i=0;i<this.scenarios.length;i++) {
								if (worldScripts["Rescue Scenario "+this.scenarios[i]].missionAvailable()) {
										for (var j=1;j<=worldScripts["Rescue Scenario "+this.scenarios[i]].missionAvailableCount();j++) {
												var scode = this.scenarios[i];
												var replaced = false;
												for(var k=0;k<this.variantscenarios.length && !replaced;k++) {
														var vcode = this.variantscenarios[k][1];
														if (usedreplacements.indexOf(vcode) == -1) { // not used this replacement already
																if (this.variantscenarios[k][0] == scode) {
																		if (worldScripts["Rescue Scenario "+vcode].missionAvailable()) {				
																				scode = vcode; // replace the scenario
																				replaced = true;
																				usedreplacements.push(vcode);
																		}
																}
														}
												}
												this.availablescenarios.push(scode);
										}
								}
						}
				} else {
						this.availablescenarios.push(this.testmode);
				}
				if (this.availablescenarios.length > 1) {
						this.availablescenarios.sort(function(a,b) { return Math.random()-0.5; }); // shuffle order
				}
				this.lastmissiongen = clock.hours;
		}
		else {
			//restore previous list of contracts
			this.availablescenarios = this.availablescenarios_save.concat();
		}
		//add station interface
		if (this.availablescenarios.length > 0)
			this.$addInterface();
		else player.ship.dockedStation.setInterface("rescue_station",null);
		
		this.availablescenarios_save = this.availablescenarios.concat();
		this.availablescenarios = new Array();
}
		
this.examineMission = function(choice) {
		if (choice == "2YES") {
			this.initMissionVariables(this.availablescenarios[this.missionpointer]);
		} else if (choice == "1NO") {
				this.missionpointer++;
		} else if (choice == "3LEAVE") {
			//create secondary board to restore board when needed
			this.availablescenarios_save = this.availablescenarios.concat();
			//clear the primary board
			this.availablescenarios = new Array();
		}
}

// f4 interface 
this.$addInterface = function() {
	if (player.ship.dockedStation.hasRole("rescue_station")) {
		player.ship.dockedStation.setInterface("rescue_station",{
			title: "RRS contract board",
			category: "Contracts",
			summary: "Enter Rescue, Recovery and Salvage Station contract board.",
			callback: this.$showInterface.bind(this)
		});
	};
};

this.$showInterface = function() {
	//restore secondary board to primary board
	this.availablescenarios = this.availablescenarios_save.concat();
	this.missionpointer = 0; //reset bulletin pointer
	this.missionScreenOpportunity(); //show board
};

/* Utility functions */

this.saveAnywhere = function() {

		if ((missionVariables.framesave == "MoveToOxpStation") || (missionVariables.framesave == "MoveToMainStation")) {
				return true; // ignore on Save-Anywhere usage
		}
		return false;

}

this.setMissionDetails = function(details) {
		mission.setInstructionsKey(details);
}

this.missionActive = function () {
		return (missionVariables.rescuestation_scenario && (missionVariables.rescuestation_stage > 0));
}

this.systemHasRescueStation = function(sysid) {
		var gov = System.infoForSystem(galaxyNumber,sysid).government;
		
		if (this.testmode != "") {
				return (gov >= 5);
		}
		

		var chance = this.rrsRandom(galaxyNumber,sysid);

		return ((gov == 7 && chance < 0.75) || // 75% corporate
						(gov == 6 && chance < 0.5) || // 50% democracy
						(gov == 5 && chance < 0.25)); // 25% confederacy
}

this.systemWithRescueHQStation = function() {
		var hqsysid;
		switch (galaxyNumber) {
		case 0:
				hqsysid = 237; // Aruszati
				break;
		case 1:
				hqsysid = 98; // Laribebi
				break;
		case 2:
				hqsysid = 5; // Lezaer
				break;
		case 3:
				hqsysid = 149; // Teance
				break;
		case 4:
				hqsysid = 35; // Enuserin
				break;
		case 5:
				hqsysid = 213; // Larivear
				break;
		case 6:
				hqsysid = 66; // Maraus
				break;
		case 7:
				hqsysid = 7; // Vegedius
				break;
		}
		return hqsysid;
}

this.systemHasRescueHQStation = function(sysid) {
		if (this.testmode == "HQ") {
				return true;
		}
		var hqsysid = this.systemWithRescueHQStation();
		return (sysid == hqsysid);
}

this.systemWillPopulate = function (){
	
	//waystations
	if (this.systemHasRescueStation(system.ID)) {
		//allow spawning of a destroyed station if on a mission.
		if (this.missionActive() || !(worldScripts.station_validator && (worldScripts.station_validator.$deaths("rescue_station").length !== 0))) {
			var sposc1 = system.mainPlanet.position.multiply(0.5);
			var sposc2 = system.sun.position.direction().multiply(sposc1.magnitude());
			var rspos = Vector3D.interpolate(sposc1,sposc2,0.3);
			system.setPopulator("rrs_waystation", {
				callback: function(pos) {			
					var rescuestation = system.addShips("rescue_station",1,pos,0)[0];
					rescuestation.orientation = [1,0,0,0]; // align with primary axis

					var rbuoy = system.addShipsToRoute("rrs_pointer",1,0.5,"wp")[0];
					rbuoy.orientation = rescuestation.position.subtract(rbuoy.position).direction().rotationTo([0,0,1]);

					var rbuoy2 = system.addShipsToRoute("rrs_pointer",1,0.5,"ws")[0];
					rbuoy2.orientation = rescuestation.position.subtract(rbuoy2.position).direction().rotationTo([0,0,1]);
					
				}.bind(this),
				location: "COORDINATES",
				coordinates: rspos,
				deterministic: true
			})
		}
	}
	
	//HQ
	if (this.systemHasRescueHQStation(system.ID)) {
		var spawnSpot = system.sun.position.cross(system.mainPlanet.position).direction().multiply(500E3);
		//allow spawning of a destroyed hq if on a mission.
		if (this.missionActive() || !(worldScripts.station_validator && (worldScripts.station_validator.$deaths("rrs_galactic_hq").length !== 0))) {
			system.setPopulator("rrs_hq", {
				callback: function(pos) {
					system.addShips("rrs_galactic_hq", 1, pos, 0);					
				}.bind(this),
				location: "COORDINATES",
				coordinates: spawnSpot,
				deterministic: true
			})
		}
		//add asteroid field even if the station has been destroyed.
		system.setPopulator("rrs_hq_asteroids", {
			callback: function(pos) {
				for (var i=0; i<4; i++) {
					var asteroids = system.addShips("asteroid",64,spawnSpot,75E3);
					for (var j=0; j<asteroids.length; j++) {
						if (asteroids[j].position.distanceTo(spawnSpot) < 15E3) {
							asteroids[j].remove(true);
						}
					}
				}
			}.bind(this),
			location: "COORDINATES",
			coordinates: spawnSpot
		})
	}
	
	//Mining bases
	
	//follow mission 6a guidelines when populating with mining base
	
	//potential system has to have disease in description. What is cause and what is effect? Who knows.
	if (!(!system.sun.hasGoneNova && (system.info.description.indexOf("disease") != -1))) {
		return;
	}
	
	//check that there is no 6a mission running to the current system
	if (missionVariables.rescuestation_scenario && (missionVariables.rescuestation_stage > 0) && (missionVariables.rescuestation_scenario === "6a") && (missionVariables.rescuestation_destsystem2 === system.ID)) {
		return;
	}
	
	//there has to be a suitable system nearby to provide meds in case of outbreak.
	//don't know if this will ever trigger though
	var medsSystems = SystemInfo.filteredSystems(this, function (other) {
				if (!((other.description.indexOf("disease") == -1) &&
							(!other.sun_gone_nova) &&
							(other.techlevel >= 11) &&
							(system.info.distanceToSystem(other) <= 45) && 
							(other.economy <= 1))) { // Rich/Avg industrials
								return false;
				} else {
						var route = system.info.routeToSystem(other);
						return (route && route.distance <= 45);
				}
	});
	if (medsSystems.length === 0) {
		return;
	}

	//Let's populate
	var i = 1;
	//find a suitable location
	do {
		var mineloc = Vector3D(system.scrambledPseudoRandomNumber(i), system.scrambledPseudoRandomNumber(i + 1), system.scrambledPseudoRandomNumber(i + 2)).multiply(400E3);
		i++;
	} while (mineloc.magnitude() < 100E3);
	//station validator support
	if (!(worldScripts.station_validator && (worldScripts.station_validator.$deaths("rrsfl-mining-outpost").length !== 0))) {
		system.setPopulator("rrs_mining_outpost", {
			callback: function(pos) {
					system.addShips("rrsfl-mining-outpost",1,pos,0);
			}.bind(this),
			location: "COORDINATES",
			coordinates: mineloc,
			deterministic: true
		});
	}
	//create the asteroid field
	system.setPopulator("rrs_mining_outpost_asteroids", {
		callback: function(pos) {
			system.addShips("asteroid", 30+Math.floor(Math.random()*30), pos, 40E3);
		}.bind(this),
		location: "COORDINATES",
		coordinates: mineloc
	});
	//add some miners
	system.setPopulator("rrs_mining_outpost_miners", {
		callback: function(pos) {
			system.addShips("miner",3,pos,20E3);
		}.bind(this),
		location: "COORDINATES",
		coordinates: mineloc
	});
	//there might be pirates lurking in the the mine
	var pirates = Math.round(Math.random()*(8 - Math.random() * system.government));
	if (pirates > 0) {
		//divide the pirates roughly into two groups
		var group1 = Math.ceil(pirates / 2);
		//add pirates around the mining outpost
		system.setPopulator("rrs_mining_outpost_pirates1", {
			callback: function(pos) {
				system.addGroup("pirate", group1, pos, 20E3);
			}.bind(this),
			location: "COORDINATES",
			coordinates: mineloc
		});
		if (pirates > group1) {
			var group2 = pirates - group1;
			system.setPopulator("rrs_mining_outpost_pirates2", {
				callback: function(pos) {
					system.addGroup("pirate", group2, pos, 20E3);
				}.bind(this),
				location: "COORDINATES",
				coordinates: mineloc
			});
		}
	}
}

this.tryAddingRescueStation = function(once) {
		if (once && this.runonce == 1) {
				return;
		}
		this.runonce = 1;
		
		if (this.missionActive() && worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_populatingSystem) {
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_populatingSystem();
		}
		worldScripts["Rescue Ambience"].addAmbience();
}

/* Generic Mission setup */

this.initMissionVariables = function(scenario) {
//		scenario = "1";
		missionVariables.rescuestation_prevreputation = missionVariables.rescuestation_reputation;
		missionVariables.rescuestation_scenario = scenario;
		missionVariables.rescuestation_stage = 1;
		worldScripts["Rescue Scenario "+scenario].initMissionVariables();

}

this.refuseCurrentMission = function () {
		this.availablescenarios.splice(this.missionpointer,1);
		//alter secondary board accordingly
		this.availablescenarios_save = this.availablescenarios.concat();
		//remove interface, if null missions
		if (this.availablescenarios.length === 0)
			player.ship.dockedStation.setInterface("rescue_station",null);
//		this.availablescenarios.shift(); // remove first mission from array
}

this.acceptMission = function () {
	//clear both boards
	this.availablescenarios = this.availablescenarios_save = new Array();
	//remove station interface
	player.ship.dockedStation.setInterface("rescue_station",null);
}

this.missionSuccess = function() {
		var sckey = missionVariables.rescuestation_scenario;
		if (!this.missionlog[sckey+"_complete"]) {
				this.missionlog[sckey+"_complete"] = 1;
		} else {
				this.missionlog[sckey+"_complete"]++;
		}
		this.syncMissionLog();
		worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].missionSuccess();
		this.cleanupMission();
		this.fillMissionBoard();
}

this.failMission = function () {
		var sckey = missionVariables.rescuestation_scenario;
		if (!this.missionlog[sckey+"_failed"]) {
				this.missionlog[sckey+"_failed"] = 1;
		} else {
				this.missionlog[sckey+"_failed"]++;
		}
		this.syncMissionLog();
		worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].failMission();
		this.cleanupMission(); // all for now
}

this.hasRankIncreased = function() {
		var rold = missionVariables.rescuestation_prevreputation;
		var rnew = missionVariables.rescuestation_reputation;
		if (rold < 320 && rnew >= 320) {
				return 6;
		} else if (rold < 160 && rnew >= 160) {
				return 5;
		} else if (rold < 80 && rnew >= 80) {
				return 4;
		} else if (rold < 40 && rnew >= 40) {
				return 3;
		} else if (rold < 20 && rnew >= 20) {
				return 2;
		} else if (rold < 10 && rnew >= 10) {
				return 1;
		}
		return 0;
}


this.reputationString = function() {
		var rep = missionVariables.rescuestation_reputation;
		if (rep < -10) {
				return "rescue_rank_0";
		} else if (rep < 0) {
				return "rescue_rank_1";
		} else if (rep < 10) {
				return "rescue_rank_2";
		} else {
				var grade = 2;
				while (rep >= 10) { // 10 20 40 80 160 320
						grade++;
						rep = rep/2;
				}
				return "rescue_rank_"+grade;
		}

}

this.cleanupMission = function() {

		if (missionVariables.rescuestation_startsystem) {
				mission.unmarkSystem({system: missionVariables.rescuestation_startsystem, name: "RRS"});
		}
		if (missionVariables.rescuestation_destsystem) {
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		}
		if (missionVariables.rescuestation_system) {
				mission.unmarkSystem({system: missionVariables.rescuestation_system, name: "RRS"});
		}

		worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].cleanupMission();

		delete missionVariables.rescuestation_scenario;

		this.setMissionDetails(this.reputationString());

		missionVariables.rescuestation_stage = 0;
}

this.getDirection = function(here,destination) {
		var d = -1;
		var xdiff = destination.coordinates.x - here.coordinates.x;
		var ydiff = here.coordinates.y - destination.coordinates.y;
		var dir = Vector3D(xdiff,ydiff,0);
		var res = "away";
		var s = 1/Math.sqrt(2);
		if (dir.dot([0,1,0]) > d) { res = "north"; d = dir.dot([0,1,0]); }
		if (dir.dot([s,s,0]) > d) { res = "northeast"; d = dir.dot([s,s,0]); }
		if (dir.dot([1,0,0]) > d) { res = "east"; d = dir.dot([1,0,0]); }
		if (dir.dot([s,-s,0]) > d) { res = "southeast"; d = dir.dot([s,-s,0]); }
		if (dir.dot([0,-1,0]) > d) { res = "south"; d = dir.dot([0,-1,0]); }
		if (dir.dot([-s,-s,0]) > d) { res = "southwest"; d = dir.dot([-s,-s,0]); }
		if (dir.dot([-1,0,0]) > d) { res = "west"; d = dir.dot([-1,0,0]); }
		if (dir.dot([-s,s,0]) > d) { res = "northwest"; d = dir.dot([-s,s,0]); }

		return res;
}

this.rrsRandom = function(galid,sysid) {
// because we can't use scrambledPseudoRandomNumber for systems we aren't in
		var n = (sysid+(galid*256))*23;
		n = (214013 * n + 2531011) & 0xFFFFFFFF;
    n = (214013 * n + 2531011) & 0xFFFFFFFF;
    n = (214013 * n + 2531011) & 0xFFFFFFFF;
		return n / 4294967296.0 + 0.5;
}

this.dangerScale = function(base) {
		if (!base) {
				base = 128;
		}
		var danger = Math.floor(Math.random()*Math.floor(1+Math.sqrt(player.score/base)));
		return danger;
}


if (this.testmode != "") {
		this.shipTargetAcquired = function(target) {
				player.consoleMessage(target.name+" "+target.AI+" "+target.AIState+" "+target.script+" "+target.primaryRole);
		}
}
Scripts/rescue_news.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue News"; 
this.description = "This script does integration with Snoopers."; 

this.startUp = function() {
		


}



this.sendNews = function(message,agency,chance) {
		if (!worldScripts.snoopers) {
				return; //optional
		}
		var priority = 3;
		if (worldScripts["Rescue Stations"].testmode != "") {
				var chance = 1.1;
				priority = 1;
		}

		if (Math.random() > chance) {
				return;
		}
		var news = new Object;
		news.ID = this.name;
		news.Message = expandMissionText(message);
		news.Agency = agency;
		news.Priority = priority;

		worldScripts.snoopers.insertNews(news);


}

this.newsDisplayed = function(message) {
// nothing right now
}
Scripts/rescue_rrs_pilot.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "RRS Pilot"; 
this.description = "This script is for RRS escape capsules"; 

this.unloadCharacter = function() {
		var payment = 200+Math.floor(Math.random()*100);
		var addpayment = 50+Math.floor(Math.random()*50);
		var message = "For rescuing RRS [rescue_random_rrsrole] "+randomName()+" "+randomName()+", a "+randomInhabitantsDescription(false)+" from [rescue_random_system], insurance pays "+payment+" Cr. (including a "+addpayment+" Cr. bonus from RRS)";
		
		missionVariables.rescuestation_reputation++;
		player.credits += payment;
		player.addMessageToArrivalReport(expandDescription(message));

}
Scripts/rescue_scenario_1.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 1"; 
this.description = "This script adds scenario 1 rescue mission."; 

//new method for selecting the mission ship -spara-
//added background images to mission screens -spara-
//random shipnames integration -spara-

this.scenarioID = "1";

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerScenario(this.scenarioID);
}

this.missionAvailableCount = function() {
		return 1;
}

this.targetSystems = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				return (other.systemID !== system.info.systemID) && 
						(!other.sun_gone_nova) &&
						(system.info.distanceToSystem(other) <= 7) &&
						(other.government < 5) // communist or less stable
		});
}

this.missionAvailable = function() {
		var nearby = this.targetSystems();
		if (nearby.length == 0) {
				return false; // no suitable nearby systems
		}
		if (missionVariables.rescuestation_reputation < 10) {
				return false; // insufficient reputation
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (Math.random() < 0.2) {
				return true; // not usually available
		}
		return false;
}

this.initMissionVariables = function() {
		var nearby = this.targetSystems();
// we don't get here unless nearby.length > 0
		var destination = nearby[Math.floor(nearby.length*Math.random())];

		missionVariables.rescuestation_danger1 = 1+worldScripts["Rescue Stations"].dangerScale(512);
		missionVariables.rescuestation_danger2 = 3+worldScripts["Rescue Stations"].dangerScale(256);
		missionVariables.rescuestation_leader_home = 0;
		missionVariables.rescuestation_derelict_home = 0;
		missionVariables.rescuestation_startsystem = system.ID;
		missionVariables.rescuestation_destsystem = destination.systemID;
		missionVariables.rescuestation_destsystem_name = destination.name;
		missionVariables.rescuestation_destsystem_type = "[rescue_govtype_"+destination.government+"]";

		var choosetype = this.$selectShip();
		missionVariables.rescuestation_shiprole = choosetype[0];
		
		if (worldScripts.randomshipnames)
			missionVariables.rescuestation_shiprole2 = choosetype[1] + ": " +  worldScripts.randomshipnames.$randomTraderName(player.ship);
		else 
			missionVariables.rescuestation_shiprole2 = choosetype[1];
				
		missionVariables.rescuestation_missionwingsize = 1;
		missionVariables.rescuestation_wingname = expandDescription("[rescue_wingnames]");

		var reward = 500;

		missionVariables.rescuestation_reward = reward;
		missionVariables.rescuestation_livefire = 0;

}

//Randomly choose a ship for the mission
this.$selectShip = function() {
	var dataKeys = Ship.keysForRole("rescue_target");
	var index = Math.floor(Math.random() * dataKeys.length);
	var shipKey = dataKeys[index];
	var roles = Ship.shipDataForKey(shipKey)["roles"].split(" ");
	for (var i = 0; i < roles.length; i++) {
		if (roles[i] != "rescue_target" && roles[i].indexOf("rescue_target") != -1) {
			return [roles[i], Ship.shipDataForKey(shipKey)["name"]];
		}
	}	
}

this.rescue_shipDockedWithStation = function (rstation) {
		if (missionVariables.rescuestation_stage > 0) {
				if (missionVariables.rescuestation_stage > 1) {
						if (missionVariables.rescuestation_stage < 1000) {
								player.commsMessage("You have docked before the rescue mission was complete. You will not be paid for this breach of contract!",7);
								worldScripts["Rescue Stations"].failMission();
						}
				}
		} 
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "URGENT: Rescue Mission Escorts Needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_1_mission_available",
														choicesKey: "rescue_scenario_urgent_mission_choices",
														model: missionVariables.rescuestation_shiprole,
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				if (missionVariables.rescuestation_livefire == 1) {
						reward = Math.round(reward*1.33);
						missionVariables.rescuestation_reward = reward;
				}
				player.credits += reward;

				mission.runScreen({title: "Rescue mission completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_1_mission_complete",
													 /*model: "EQ_RESCUE_MISSILE",*/
													 background: "rrsfl_bg.png",});

				worldScripts["Rescue Stations"].missionSuccess();

		}
}


this.rescue_shipWillLaunchFromStation = function (rstation) {
		if (missionVariables.rescuestation_stage == 2 && rstation.hasRole("rescue_station")) {
				var addpos = rstation.position.add([0,0,10E6-5E3]);
				
				var leader = system.addShips("rescue_team_lead",1,addpos,10);
				leader[0].orientation = leader[0].orientation.rotateY(Math.PI);
				leader[0].position = rstation.position.add([0,0,-5E3]);
				for(var i=0;i<leader[0].escorts.length;i++) {
						var escort = leader[0].escorts[i];
						escort.orientation = escort.orientation.rotateY(Math.PI);
						escort.position = leader[0].position.add([1500-(Math.random()*3000),500-(Math.random()*1000),0.6E3*(1+i)]);
						//escort.speed = escort.maxSpeed/3;
				}
				
				missionVariables.rescuestation_stage = 3;
		}

}

this.rescue_populatingSystem = function() {
		if (missionVariables.rescuestation_stage == 10 && system.ID == missionVariables.rescuestation_destsystem) {
				missionVariables.rescuestation_stage = 11;

//				addpos = this.randomOffset(60E3);
				var addpos = this.randomOffset(150E3*(1+(2*Math.random())));

				var addedShip = system.addShips(missionVariables.rescuestation_shiprole,1,addpos,1);

				if (worldScripts.randomshipnames)
					addedShip[0].displayName = missionVariables.rescuestation_shiprole2;
				else
					addedShip[0].displayName = addedShip[0].name + " (derelict)";

				var addpos2 = addpos.direction().multiply(80E3*Math.random());
				
				if (Math.random()+(system.government/20) < 0.85) {
						var pirates = system.addShips("pirate",missionVariables.rescuestation_danger1+Math.floor(Math.random()*missionVariables.rescuestation_danger2),addpos2,3E3);
						this.forceAssault(pirates);
				}

				if (addpos.magnitude() > 200E3) {
						addpos2 = addpos.direction().multiply(100E3+(80E3*Math.random()));

						if (Math.random()+(system.government/20) < 0.85) {
								system.addGroup("pirate",missionVariables.rescuestation_danger1+Math.floor(Math.random()*missionVariables.rescuestation_danger2),addpos2,3E3);
						}
						
				}

		}

}

this.rescue_shipWillExitWitchspace = function() {
		
}

/* Mission setup */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 5;
		if (missionVariables.rescuestation_livefire == 1) {
				missionVariables.rescuestation_reputation += 5;
		}
		
		worldScripts["Rescue News"].sendNews("rescue_scenario_1_news",0,0.03);
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 5;
		// nothing special
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_callsign;
		delete missionVariables.rescuestation_missionwingsize;
		delete missionVariables.rescuestation_wingname;
		delete missionVariables.rescuestation_startsystem;
		delete missionVariables.rescuestation_destsystem;
		delete missionVariables.rescuestation_destsystem_name;
		delete missionVariables.rescuestation_destsystem_type;
		delete missionVariables.rescuestation_shiprole;
		delete missionVariables.rescuestation_shiprole2;
		delete missionVariables.rescuestation_leader_home;
		delete missionVariables.rescuestation_derelict_home;
		delete missionVariables.rescuestation_livefire;
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_danger1;
		delete missionVariables.rescuestation_danger2;

}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Downloading mission data",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_1_mission_accepted",
													 choicesKey: "rescue_scenario_urgent_mission_launch",
													 model: "rescue_team_lead",
													 background: "rrsfl_blank_bg.png",},
													worldScripts["Rescue Scenario 1"].missionOfferAccepted
												 );
		}
}

this.missionOfferAccepted = function (choice) {
		worldScripts["Rescue Stations"].acceptMission();
		worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_1_description");
		player.ship.fuel = 7;
		player.ship.launch();
}

/* Mission functions */

this.followToDest = function(mass) {
		var expirytime = 50 + (mass/4000);
		this.followtimer = new Timer (this, this.checkFollowed, expirytime);
}

this.checkFollowed = function() {
		if (missionVariables.rescuestation_stage > 0) {
				if (system.countShipsWithRole("arafura-mission") == 0) {
						player.consoleMessage("You have failed to follow your leader through witch-space. Mission failed",7);
						this.failMission();
				}
		}
}

this.forceAssault = function(attackers) {
		for(var i=0;i<attackers.length;i++) {
				var targets = system.filteredEntities(this,function(entity) {
						return (entity == player.ship) || (entity.hasRole == "arafura-mission");
				},attackers[i],25600);
				if (targets.length > 0) {
						var target = targets[Math.floor(Math.random()*targets.length)];
						attackers[i].target = target;
						attackers[i].setAI("interceptAI.plist");
				}
		}
}

this.randomOffset = function(basedist) {
		return Vector3D.randomDirection(basedist);
}
Scripts/rescue_scenario_1_derelict.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1a Derelict";
this.description = "Scripts for the Derelicts";

//typo fix -spara-
//random shipnames tweak -spara-

this.repairWait = function() {
		this.repairTimer = new Timer (this, this.repairDone, 15+(10*Math.random()));
}

this.whatamessMessage = function() {
		this.ship.commsMessage("[rescue_whatamess_"+missionVariables.rescuestation_scenario+"].");
}

this.repairDone = function() {
		this.ship.reactToAIMessage("REPAIR_NEXT");
		if (missionVariables.rescuestation_stage > 0) {
				missionVariables.rescuestation_stage++;
				if (missionVariables.rescuestation_stage == 14) {
						var rocks = system.entitiesWithScanClass("CLASS_ROCK",this.ship,25E3);
						var found = false;
						for (var i=0;i<rocks.length;i++) {
								var rock = rocks[i];
								if (rock.velocity.magnitude() > 0) {
										rock.scannerDisplayColor1 = "whiteColor";
										rock.scannerDisplayColor2 = "redColor";
										found = true;
								}
						}

						if (found) {
								this.ship.commsMessage("I'm detecting a few asteroids on a potential collision course. Sending co-ordinates to your scanners now.");
						}

				}
		}
}

this.repairsBegin = function() {
		if (Math.random()+(system.government/20) < 0.85) {
				this.attackTimer = new Timer (this, this.attackBegin, 3+(15*Math.random()));
		}
}

this.repairsEnd = function() {
	if (!worldScripts.randomshipnames)
		this.ship.displayName = this.ship.name+" (Rescued)";
}

this.attackBegin = function() {
		var addpos = this.ship.position.add([0,0,23E3]); // from planetwards
		var pirates = system.addShips("pirate",missionVariables.rescuestation_danger1+Math.floor(Math.random()*missionVariables.rescuestation_danger2),addpos,2E3);
		worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].forceAssault(pirates);
}

this.shipDied = function(whom,why) {
		if (whom == player.ship) {
				missionVariables.rescuestation_reputation -= 10;
		}

		player.consoleMessage("Rescue Mission: "+this.ship.displayName+" has been destroyed. Mission failed.");
		missionVariables.rescuestation_stage = 0;
		worldScripts["Rescue Stations"].failMission();
/*		if (whom) {
				player.consoleMessage(this.ship.displayName+" killed by "+whom.displayName+" using "+why);
		} else {
				player.consoleMessage(this.ship.displayName+" killed by anonymous using "+why);
		}*/
}

this.failedToFollow = function() {
		player.consoleMessage("Rescue Mission: "+this.ship.displayName+" has failed to enter witch-space. Mission failed.");
		missionVariables.rescuestation_stage = 0;
		worldScripts["Rescue Stations"].failMission();

}

this.energyFail = function() {
		if (this.ship.energy > 40) {
				this.ship.energy = 40;
		}
}

this.addToRescueGroup = function() {

		var leader = system.shipsWithRole("arafura-mission",this.ship,25E3);
//		player.consoleMessage("Multiple leaders? ("+leader.length+")");
		if (leader.length >= 1) {
				this.target = leader[0];
//				this.ship.commsMessage("Ready to go");
				leader[0].reactToAIMessage("READY_TO_GO");
				if (missionVariables.rescuestation_stage > 0 && missionVariables.rescuestation_stage < 90) {
						missionVariables.rescuestation_stage = 90;
				}
				this.ship.reactToAIMessage("LEADER_FOUND");
				this.ship.savedCoordinates = leader[0].position;
		} else {
				this.ship.reactToAIMessage("NO_LEADER_FOUND");
		}

}

this.checkSystem = function() {
		if (missionVariables.rescuestation_stage < 100) {
				this.ship.reactToAIMessage("REMOTE_SYSTEM");
		} else {
				this.ship.reactToAIMessage("HOME_SYSTEM");
		}
}

this.inboundJump = function() {
		this.ship.fuel = 7;
		if (!this.ship.exitSystem(missionVariables.rescuestation_startsystem)) {
				this.ship.reactToAIMessage("JUMP_FAILED");
		}
}


this.locateArafura = function() {
		var arafura = system.shipsWithRole("arafura-mission");
		if (arafura.length == 0) {
				this.ship.reactToAIMessage("NO_ARAFURA_FOUND");
		} else {
				var station = system.shipsWithRole("rescue_station",this.ship,20000);
				if (station.length > 0) {
						this.ship.reactToAIMessage("STATION_NEARBY");
				}

				this.ship.savedCoordinates = arafura[0].position;
				this.ship.reactToAIMessage("ARAFURA_FOUND");
		}
}

this.locateHomeStation = function() {
		var station = system.shipsWithRole("rescue_station");
		if (station.length == 0) {
				this.ship.reactToAIMessage("NO_HOME_STATION");
		} else {
				if (this.ship.position.distanceTo(station[0].position) < 20000) {
						this.ship.target = station[0];
				}
				this.ship.savedCoordinates = station[0].position;
				this.ship.reactToAIMessage("HOME_STATION");
		}
}

this.shipDockedWithStation = function(station) {
		if (missionVariables.rescuestation_stage >= 100) {
				missionVariables.rescuestation_derelict_home = 1;
				if (missionVariables.rescuestation_leader_home == 1) {
						missionVariables.rescuestation_stage = 1000;
						station.commsMessage("Thank you for your services, Commander [commander_name]. Please dock to receive payment.");
				}
		} else if (missionVariables.rescuestation_stage > 0) {
				player.consoleMessage("Rescue Mission: "+this.ship.displayName+" has not reached the rescue station. Mission aborted.");
				worldScripts["Rescue Stations"].failMission();
		}
}


this.fakeHyperJump = function() {
		// if the player jumps out first it seems a bit random whether this one manages to follow
		this.ship.exitSystem(missionVariables.rescuestation_startsystem);
}

this.shipTakingDamage = function(amount,whom,type) {
		if (type == "scrape damage" && (whom.hasRole("arafura-mission"))) {
				this.ship.energy += amount; // cancel damage from collision with leader
		}
}

this.shipExitedWormhole = function() {
// try to reduce collisions from following
//		this.ship.position = this.ship.position.add([-3E3,-3E3,-3E3]);
}
Scripts/rescue_scenario_1_escort.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1 Escort";
this.description = "Scripts for the Escorts";


this.shipDied = function(whom,why) {
		this.ship.commsMessage("[rescue_argh]");
		if (whom == player.ship) {
				missionVariables.rescuestation_reputation -= 10;
		}
/*		if (whom) {
				player.consoleMessage(this.ship.displayName+" killed by "+whom.displayName+" using "+why);
		} else {
				player.consoleMessage(this.ship.displayName+" killed by anonymous using "+why);
		}*/

}

Scripts/rescue_scenario_1_leader.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1 Leader";
this.description = "AI for the Moray Rescue Leader";

//changed shipname to random shipnames style -spara-

this.escortnum = 2;
this.playercallsign = "";
this.damagelevel = 0;

this.entryCheckMissionState = function() {
		if (this.ship.displayName.indexOf(":") === -1) {
			this.ship.displayName = this.ship.displayName + ": " + missionVariables.rescuestation_wingname + " Leader";
		}
		if (this.ship.escorts) {
				for (var i=0;i<this.ship.escorts.length;i++) {
						if (this.escortnum == 4) {
								this.escortnum++; // 4 is player
						}
						var escortship = this.ship.escorts[i]
						if (escortship.displayName.indexOf(":") === -1) {
								escortship.displayName = escortship.displayName + ": " + missionVariables.rescuestation_wingname+" "+(this.escortnum++);
						}
				}
		}

		if (missionVariables.rescuestation_stage == 0) {
				this.ship.reactToAIMessage("RETURN_TO_BASE");
		} else if (missionVariables.rescuestation_stage < 10) {
				this.ship.reactToAIMessage("READY_TO_LEAVE");
		} else if (missionVariables.rescuestation_stage < 100) {
				this.ship.reactToAIMessage("IN_SYSTEM");
		} else {
				this.ship.reactToAIMessage("RETURN_TO_BASE");
		}
}

this.beginMission = function() {
		missionVariables.rescuestation_callsign = missionVariables.rescuestation_wingname+" 4";
		
		this.ship.commsMessage("Welcome, Commander "+player.name+". You will be taking the "+missionVariables.rescuestation_callsign+" flight position for this trip. Form up in preparation for witch-space jump.",player.ship);
		missionVariables.rescuestation_stage = 4;
}

this.checkEscortsNear = function () {
		var maxdistance = this.ship.position.distanceTo(player.ship.position);
		if (this.ship.escorts) {
				for (var i=0;i<this.ship.escorts.length;i++) {
						var escortship = this.ship.escorts[i]
						var distance = this.ship.position.distanceTo(escortship.position);
						if (distance < 25E3) { // ignore those outside scanner range
								if (distance > maxdistance) {
										maxdistance = distance;
								}
						}
				}
		}
		if (maxdistance > 5000) {
				this.ship.reactToAIMessage("ESCORTS_FAR");
		} else {
				this.ship.reactToAIMessage("ESCORTS_NEAR");
		}
}
		
this.recallEscortsForJump = function() {
		this.ship.commsMessage("Preparing for witch-space jump. All "+missionVariables.rescuestation_wingname+"s, approach to within 5km.",player.ship);
		this.recallEscorts();

		this.setOutboundJumpCoordinates();
}

this.setOutboundJumpCoordinates = function() {
		var station = system.shipsWithPrimaryRole("rescue_station",this.ship,25600);
		if (station.length > 0) {
				this.ship.savedCoordinates = station[0].position.add([0,0,-8E3]);

		} else {
				this.ship.savedCoordinates = player.ship.position;
		}
}

this.setDestinationToPlayer = function() {
		this.ship.savedCoordinates=player.ship.position;
}

this.keepEscortsClose = function() {
		// if any escort is more than 20km away, send it a recall message
		if (this.ship.escorts) {
				for (var i=0;i<this.ship.escorts.length;i++) {
						var escortship = this.ship.escorts[i];
						if (
								(escortship.target && 
								 (
										 (this.ship.position.distanceTo(escortship.position) > 20E3 &&
											this.ship.position.distanceTo(escortship.target.position) > 20E3
										 ) ||
												 this.ship.position.distanceTo(escortship.target.position) > 26E3
								 )
								) || 
										(!escortship.target && this.ship.position.distanceTo(escortship.position) > 10E3)
						) {
								this.recallEscort(escortship);
						}
				}		
		}
}

this.recallEscort = function(escortship) {
		if (escortship.AI == "interceptAI.plist") {
				this.ship.commsMessage(escortship.displayName+", return to escort formation.");
				escortship.exitAI(); // return to escorting
		}
}

this.recallEscorts = function() {
				if (this.ship.escorts) {
		for (var i=0;i<this.ship.escorts.length;i++) {
				var escortship = this.ship.escorts[i];
				this.recallEscort(escortship);
		}		
				}
}

this.prepareOutboundJump = function() {
		this.ship.commsMessage("Initialising witch-space jump to "+missionVariables.rescuestation_destsystem_name+". All "+missionVariables.rescuestation_wingname+"s, follow me.",player.ship);
		this.ship.reactToAIMessage("JUMP_READY");
}

this.outboundJump = function() {
		this.ship.fuel = 7;
		if (!this.ship.exitSystem(missionVariables.rescuestation_destsystem)) {
				this.ship.reactToAIMessage("JUMP_FAILED");
		} else {
				missionVariables.rescuestation_stage = 10; // second stage of mission
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].followToDest(this.ship.mass);
		}
}

this.inboundJump = function() {
		this.ship.fuel = 7;
		var derelict = system.shipsWithRole(missionVariables.rescuestation_shiprole);
		if (derelict.length == 0) {
				this.ship.reactToAIMessage("NO_DERELICT");
		} else {
				this.ship.group = new ShipGroup("rescuegroup",this.ship);
				this.ship.group.addShip(this.ship);
				this.ship.group.addShip(derelict[0]);
		}

		if (!this.ship.exitSystem(missionVariables.rescuestation_startsystem)) {
				this.ship.reactToAIMessage("JUMP_FAILED");
		} else {
				missionVariables.rescuestation_stage = 100; // second stage of mission
				worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].followToDest(this.ship.mass);
		}
}


this.jumpFailed = function() {
		if (Math.random() < 0.2) {
				this.ship.commsMessage("Witch-space jump failed. Reinitialising...",player.ship);
		}
}

this.shipExitedWormhole = function() {
// try to reduce collisions from followers
//		this.ship.velocity = this.ship.velocity.add(this.ship.vectorForward.multiply(this.ship.maxSpeed));
//		this.ship.position = this.ship.position.add(this.ship.vectorForward.multiply(3E3));
}

this.stationLost = function() {
		player.consoleMessage("Rescue Mission: the rescue station has been destroyed. Don't expect any pay now.");
		missionVariables.rescuestation_stage = 0;
		worldScripts["Rescue Stations"].failMission();
}

this.shipDied = function(whom,why) {
		if (whom == player.ship) {
				missionVariables.rescuestation_reputation -= 20;
		}
		player.consoleMessage("Rescue Mission: "+this.ship.displayName+" has been destroyed. Mission failed.");
		missionVariables.rescuestation_stage = 0;
		worldScripts["Rescue Stations"].failMission();
		if (this.ship.escorts) {
				for (var i=0;i<this.ship.escorts.length;i++) {
						var escortship = this.ship.escorts[i]
						escortship.displayName = escortship.name; // remove designations
				}
		}
/*		if (whom) {
				player.consoleMessage(this.ship.displayName+" killed by "+whom.displayName+" using "+why);
		} else {
				player.consoleMessage(this.ship.displayName+" killed by anonymous using "+why);
		} */
}

this.clearRocks = function () {
		this.ship.commsMessage(missionVariables.rescuestation_callsign+", could you clear out some of these asteroids? Other escorts stay close to me for defence.",player.ship);
}

this.returnToMission = function () {
		this.ship.commsMessage("That's all of them. Return to flight formation.",player.ship);
		this.recallEscorts();
}

this.requireEscort = function () {
		missionVariables.rescuestation_livefire = 1;
		if (!this.ship.target) {
				return;
		}
		if (this.ship.target.isWeapon) {
				return; // gives some odd messages
		}
		if (this.ship.target.hasRole("thargon")) {
				var mothership = system.shipsWithRole("thargoid-mothership",this.ship,25600);
				if (mothership.length > 0) {
						// escorts don't have great aim, so better if they go for the motherships
						this.ship.target = mothership[0];
				}
		}
		if (this.ship.isThargoid) {
				this.requireAllEscorts();
				return;
		}
		var closest = 27E3;
		if (this.ship.escorts) {
				for (var i=0;i<this.ship.escorts.length;i++) {
						var escortship = this.ship.escorts[i]
						var distance = this.ship.position.distanceTo(escortship.position);
						if (closest > distance) {
								var requestship = escortship;
								closest = distance;
						}
				}
		}
		if (player.ship.position) {
				var distance = this.ship.position.distanceTo(player.ship.position);
		} else {
				var distance = 50E3;
		}
		if (closest > distance) {
				var requestship = player.ship;
				var requestname = escortship.displayName;
				closest = distance;
				if (missionVariables.rescuestation_stage > 0) {
						this.requirePlayerHelp();
				}
		} else if (closest < 27E3) {
				this.requireEscortHelp(requestship,false);
		} else {
				player.commsMessage(this.ship.displayname+": I'm under attack! All "+missionVariables.rescuestation_wingname+" return to scanner range immediately!");
		}
}

this.requireAllEscorts = function() {
		if (this.ship.escorts) {
				this.ship.commsMessage("All "+missionVariables.rescuestation_wingname+", target the "+this.ship.target.displayName+".");
				for (var i=0;i<this.ship.escorts.length;i++) {
						var escortship = this.ship.escorts[i]
						this.requireEscortHelp(escortship,true);
				}
		}
}

this.requirePlayerHelp = function() {
		if (this.ship.target && this.ship.target != player.ship.target) {
				this.ship.commsMessage(missionVariables.rescuestation_callsign+", target the "+this.ship.target.displayName+".");
		} else {
//				this.ship.commsMessage("We're under attack! "+missionVariables.rescuestation_callsign+", fire at will!");
		}
}

this.requireEscortHelp = function(escort,quiet) {
		if (escort.target != this.ship.target) {
				if (!quiet) {
						this.ship.commsMessage(escort.displayName+", target the "+this.ship.target.displayName+".");
				}
				escort.target = this.ship.target;
				escort.setAI("interceptAI.plist");
		}
}

this.takingDamage = function() {
		if (this.damagelevel == 0) {
				this.damagelevel = 1;
				this.ship.commsMessage("I'm taking substantial damage! "+missionVariables.rescuestation_callsign+", target the "+this.ship.target.displayName+" immediately!");
		}
}

this.takingHeavyDamage = function() {
		if (this.damagelevel < 2) {
				this.damagelevel = 2;
				this.ship.commsMessage("Energy banks are failing! Get these hostiles away from me!");
		}
}

this.resetDamageCounter = function() {
		this.damagelevel = 0;
}

this.checkEscortAlert = function() {
		if (player.alertCondition == 3 || player.alertHostiles) {
				var attackers = system.filteredEntities(this,function(entity) {
						return (entity.target == player.ship) && entity.isShip && entity.hasHostileTarget;
				},this.ship,25600);
				if (attackers.length > 0) {
						this.ship.target = attackers[0];
				}
				this.ship.reactToAIMessage("PLAYER_RED");
		} else {
				if (this.ship.escorts) {
						for (var i=0;i<this.ship.escorts.length;i++) {
								var escortship = this.ship.escorts[i]
								var attackers = system.filteredEntities(this,function(entity) {
										return (entity.target == escortship) && entity.isShip && entity.hasHostileTarget;
								},this.ship,25600);
								if (attackers.length > 0) {
										this.ship.target = attackers[0];
										this.ship.reactToAIMessage("ESCORT_RED");
										return;
								}
						}
				}
				this.ship.reactToAIMessage("PLAYER_OK");
		}
}

this.locateDerelict = function() {
		var derelict = system.shipsWithRole(missionVariables.rescuestation_shiprole);
		if (derelict.length == 0) {
				this.ship.reactToAIMessage("NO_DERELICT");
		} else {
				this.ship.savedCoordinates = derelict[0].position;
				this.ship.reactToAIMessage("DERELICT_FOUND");
		}
}

this.generalChatter = function() {
		if (this.ship.escorts && Math.random() < 0.3) {
				var speakerno = Math.floor(Math.random()*this.ship.escorts.length);
				var speaker = this.ship.escorts[speakerno];
		} else {
				var speaker = this.ship;
		}
		speaker.commsMessage("[rescue_radiochatter]");
}

this.launchEVA = function() {
		var derelict = system.shipsWithRole(missionVariables.rescuestation_shiprole);
		if (derelict.length == 0) {
				this.ship.reactToAIMessage("NO_DERELICT");
		} else {
				this.ship.target = derelict[0];
				this.ship.awardEquipment("EQ_RESCUE_MISSILE");
				this.ship.fireMissile("EQ_RESCUE_MISSILE");
				this.ship.target = null; /* prevent really silly mission failure */
		}
}

this.locateHomeStation = function() {
		var station = system.shipsWithRole("rescue_station");
		if (station.length == 0) {
				this.ship.reactToAIMessage("NO_HOME_STATION");
		} else {
				if (this.ship.position.distanceTo(station[0].position) < 20000) {
						this.ship.target = station[0];
				}
				this.ship.savedCoordinates = station[0].position;
				this.ship.reactToAIMessage("HOME_STATION");
		}
}

this.shipDockedWithStation = function(station) {
		if (missionVariables.rescuestation_stage >= 100) {
				missionVariables.rescuestation_leader_home = 1;
				if (missionVariables.rescuestation_derelict_home == 1) {
						missionVariables.rescuestation_stage = 1000;
						station.commsMessage("Thank you for your services, Commander [commander_name]. Please dock to receive payment.");
				}
		} else if (missionVariables.rescuestation_stage > 0) {
				player.consoleMessage("Rescue Mission: "+this.ship.displayName+" has docked before the mission is complete. Mission aborted.");
				worldScripts["Rescue Stations"].failMission();
		}
}

this.shipTakingDamage = function(amount,whom,type) {
		if (type == "scrape damage" && (whom.hasRole("rrs-escort") || whom.hasRole("rescue_target"))) {
				this.ship.energy += amount; // cancel damage from collision with follower
		}
}




/* Autopilot functions block */

this.autopilotModeReady = function() {
		this.autopilotwilling = 1;
}

this.autopilotModeOffline = function() {
		this.autopilotwilling = 0;
}

this.autopilotContinue = function() {
		worldScripts["Rescue Autopilot"].autopilotStep(this.ship);
}
Scripts/rescue_scenario_1a.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 1a"; 
this.description = "This script adds scenario 1 variant A rescue mission."; 

//added background images to mission screens -spara-
//random shipnames integration -spara-

this.scenarioID = "1a";

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("1",this.scenarioID);
}

this.missionAvailableCount = function() {
		return 1;
}

this.missionAvailable = function() {
		if (worldScripts["Rescue Stations"].scenariosWon("1") == 0) {
				return false; // it's a little trickier, so not the first time
		}
		if (2*worldScripts["Rescue Stations"].scenariosWon("1a") > worldScripts["Rescue Stations"].scenariosWon("1")) {
				return false; // no more than 1 in 3
		}
		if (Math.random() < 0.4) {
				return true; // occasional replacement
		}
		return false;
}

this.initMissionVariables = function() {
		worldScripts["Rescue Scenario 1"].initMissionVariables();
}

this.rescue_shipDockedWithStation = function (rstation) {
		worldScripts["Rescue Scenario 1"].rescue_shipDockedWithStation(rstation);
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "URGENT: Rescue Mission Escorts Needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_1_mission_available",
														choicesKey: "rescue_scenario_urgent_mission_choices",
														model: missionVariables.rescuestation_shiprole,
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				if (missionVariables.rescuestation_livefire == 1) {
						reward = Math.round(reward*1.33);
						missionVariables.rescuestation_reward = reward;
				}
				player.credits += reward;

				mission.runScreen({title: "Rescue mission completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_1_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();

		}
}


this.rescue_shipWillLaunchFromStation = function (rstation) {
		worldScripts["Rescue Scenario 1"].rescue_shipWillLaunchFromStation(rstation);
}


this.rescue_populatingSystem = function() {
		if (missionVariables.rescuestation_stage == 10 && missionVariables.rescuestation_destsystem == system.ID) {
				missionVariables.rescuestation_stage = 11;

				var addpos = this.randomOffset(60E3);
				
				var addedShip = system.addShips(missionVariables.rescuestation_shiprole,1,addpos,1);

				if (worldScripts.randomshipnames)
					addedShip[0].displayName = missionVariables.rescuestation_shiprole2;
				else
					addedShip[0].displayName = addedShip[0].name + " (derelict)";
				
				this.addAsteroids(addpos);

				var addpos2 = this.randomOffset(15E3);
				
				if (Math.random() < 0.75) {
						var pirates = system.addShips("pirate",missionVariables.rescuestation_danger1+Math.floor(Math.random()*missionVariables.rescuestation_danger2),addpos2,3E3);
						this.forceAssault(pirates);
				}

		}
}

/* Mission setup */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 5;
		if (missionVariables.rescuestation_livefire == 1) {
				missionVariables.rescuestation_reputation += 5;
		}
		// nothing special		
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 5;
		// nothing special
}

this.cleanupMission = function() {
		worldScripts["Rescue Scenario 1"].cleanupMission();
}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Downloading mission data",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_1_mission_accepted",
													 choicesKey: "rescue_scenario_urgent_mission_launch",
													 model: "rescue_team_lead",
													 background: "rrsfl_blank_bg.png"},
													worldScripts["Rescue Scenario 1"].missionOfferAccepted
												 );
		}
}

this.missionOfferAccepted = function (choice) {
		worldScripts["Rescue Stations"].acceptMission();
		worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_1_description");
		player.ship.fuel = 7;
		player.ship.launch();
}

/* Mission functions */

this.followToDest = function(mass) {
		var expirytime = 50 + (mass/4000);
		this.followtimer = new Timer (this, this.checkFollowed, expirytime);
}

this.checkFollowed = function() {
		worldScripts["Rescue Scenario 1"].checkFollowed();
}

this.forceAssault = function(attackers) {
		worldScripts["Rescue Scenario 1"].forceAssault(attackers);
}

this.randomOffset = function(basedist) {
		return worldScripts["Rescue Scenario 1"].randomOffset(basedist);
}

this.addAsteroids = function(dpos) {
		var cpos = dpos.add(Vector3D.random(5E3));
		var asteroids = 100;
		var fieldradius = 30E3;
		for (var i=0;i<asteroids;i++) {
				var apos = cpos.add(Vector3D.randomDirectionAndLength(fieldradius));
				var aster = system.addShips("asteroid",1,apos,1E3);

				if (aster[0].position.distanceTo(dpos) > 20E3 && Math.random() < 0.5) {
						var vel = dpos.subtract(aster[0].position);
						
						aster[0].velocity = vel.multiply((2+(Math.random()*9))/(5E3));
				}
		}

		

}
Scripts/rescue_scenario_1a_derelict.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1a Derelict";
this.description = "Scripts for the Derelicts";

this.revert = function() {
		this.ship.setScript("rescue_scenario_1_derelict.js");
		this.ship.switchAI("rescue_scenario_1_derelictAI.plist");
}
Scripts/rescue_scenario_1a_escort.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1a Escort";
this.description = "Scripts for the Escorts";


this.shipDied = function(whom,why) {
		this.ship.commsMessage("[rescue_argh]");

/*		if (whom) {
				player.consoleMessage(this.ship.displayName+" killed by "+whom.displayName+" using "+why);
		} else {
				player.consoleMessage(this.ship.displayName+" killed by anonymous using "+why);
		} */

}
Scripts/rescue_scenario_1a_leader.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1a Leader";
this.description = "AI for the Moray Rescue Leader";

this.revert = function() {
		this.ship.setScript("rescue_scenario_1_leader.js");
		this.ship.switchAI("rescue_scenario_1_leaderAI.plist");
}
Scripts/rescue_scenario_1b.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 1b"; 
this.description = "This script adds scenario 1 variant B rescue mission."; 

//added background images to mission screens -spara-
//random shipnames integration -spara-
//anomalies added as visual effects -spara-


this.scenarioID = "1b";

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("1",this.scenarioID);
}

this.missionAvailableCount = function() {
		return 1;
}

this.missionAvailable = function() {
		if (missionVariables.rescuestation_reputation < 40) {
				return false; // Tier 3 contractor needed
		}
		if (worldScripts["Rescue Stations"].scenariosWon("1") < 5) {
				return false; // somewhat rare variation
		}
		if (10*worldScripts["Rescue Stations"].scenariosWon("1") > worldScripts["Rescue Stations"].scenariosTried("1b")) {
				return false; // no more than 1 in 10
		}
		if (Math.random() < 0.3) {
				return true; // occasional replacement
		}
		return false;
}

this.initMissionVariables = function() {
		worldScripts["Rescue Scenario 1"].initMissionVariables();
}

this.rescue_shipDockedWithStation = function (rstation) {
		worldScripts["Rescue Scenario 1"].rescue_shipDockedWithStation(rstation);
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "URGENT: Rescue Mission Escorts Needed",
													screenID: "rrs_mission",
														messageKey: "rescue_scenario_1b_mission_available",
														choicesKey: "rescue_scenario_urgent_mission_choices",
														model: missionVariables.rescuestation_shiprole,
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				if (missionVariables.rescuestation_livefire == 1) {
						reward = Math.round(reward*1.5);
						missionVariables.rescuestation_reward = reward;
				}
				player.credits += reward;

				mission.runScreen({title: "Rescue mission completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_1b_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();

		}
}


this.rescue_shipWillLaunchFromStation = function (rstation) {
		if (missionVariables.rescuestation_stage == 2 && rstation.hasRole("rescue_station")) {
				var addpos = rstation.position.add([0,0,10E6-5E3]);
				
				var leader = system.addShips("rescue_team_lead_2",1,addpos,10);
				leader[0].orientation = leader[0].orientation.rotateY(Math.PI);
				leader[0].position = rstation.position.add([0,0,-5E3]);
				for(var i=0;i<leader[0].escorts.length;i++) {
						var escort = leader[0].escorts[i];
						escort.orientation = escort.orientation.rotateY(Math.PI);
						escort.position = leader[0].position.add([1500-(Math.random()*3000),500-(Math.random()*1000),0.6E3*(1+i)]);
						//escort.speed = escort.maxSpeed/3;
				}
				
				missionVariables.rescuestation_stage = 3;
		}
}


this.rescue_populatingSystem = function() {
		if (missionVariables.rescuestation_stage == 10 && missionVariables.rescuestation_destsystem == system.ID) {
				missionVariables.rescuestation_stage = 11;

				var addpos = this.randomOffset(100E3*(1+(2*Math.random())));

				var addedShip = system.addShips(missionVariables.rescuestation_shiprole,1,addpos,1);

				if (worldScripts.randomshipnames)
					addedShip[0].displayName = missionVariables.rescuestation_shiprole2;
				else
					addedShip[0].displayName = addedShip[0].name + " (derelict)";
				

		} else if (missionVariables.rescuestation_stage == 100 && missionVariables.rescuestation_startsystem == system.ID) {
				var danger1 = Math.floor(Math.random()*(missionVariables.rescuestation_danger1-1));
				if (danger1 > 0) {
					for (var i = 0; i < danger1; i++)
						system.addVisualEffect("rrs_witchspace_anomaly",Vector3D.randomDirectionAndLength(20E3));
				}
				if (worldScripts["GalNavy"] && Math.random() < 0.8) { // Galactic Navy OXP available
						system.addShips("patrol-frigate",1,[0,0,0],10E3);
						var danger2 = Math.floor(0.5*Math.random()*missionVariables.rescuestation_danger2);
						if (danger2 > 0) {
							for (var i = 0; i < danger2; i++)
								system.addVisualEffect("rrs_witchspace_anomaly",Vector3D.randomDirectionAndLength(20E3));
						}
				}
				
		}
}

/* Mission setup */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 5;
		if (missionVariables.rescuestation_livefire == 1) {
				// basically always
				missionVariables.rescuestation_reputation += 10;
		}
		// nothing special		
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 5;
		// nothing special
}

this.cleanupMission = function() {
		worldScripts["Rescue Scenario 1"].cleanupMission();
}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Downloading mission data",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_1_mission_accepted",
													 choicesKey: "rescue_scenario_urgent_mission_launch",
													 model: "rescue_team_lead",
													 background: "rrsfl_blank_bg.png"},
													worldScripts["Rescue Scenario 1b"].missionOfferAccepted
												 );
		}
}

this.missionOfferAccepted = function (choice) {
		worldScripts["Rescue Stations"].acceptMission();
		worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_1_description");
		player.ship.fuel = 7;
		player.ship.launch();
}

/* Mission functions */

this.followToDest = function(mass) {
		var expirytime = 50 + (mass/4000);
		this.followtimer = new Timer (this, this.checkFollowed, expirytime);
}

this.checkFollowed = function() {
		worldScripts["Rescue Scenario 1"].checkFollowed();
}

this.forceAssault = function(attackers) {
		worldScripts["Rescue Scenario 1"].forceAssault(attackers);
}

this.randomOffset = function(basedist) {
		return worldScripts["Rescue Scenario 1"].randomOffset(basedist);
}

Scripts/rescue_scenario_1b_derelict.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1b Derelict";
this.description = "Scripts for the Derelicts";

//anomalies added as visual effects -spara-

this.revert = function() {
		this.ship.setScript("rescue_scenario_1_derelict.js");
		this.ship.switchAI("rescue_scenario_1_derelictAI.plist");
		// function overrides

		this.ship.script.repairsBegin = function() {
				this.attackTimer = new Timer (this, this.thargoidAttackBegin, 33+(15*Math.random()));
		}
		this.ship.script.repairWait = function() {
				if (missionVariables.rescuestation_stage <= 12) {
						this.repairTimer = new Timer (this, this.repairDone, 15+(10*Math.random()));		
				} else {
						this.repairTimer = new Timer (this, this.repairDone, 25+(25*Math.random()));
				}
		}

		this.ship.script.thargoidAttackBegin = function() {
				var danger = 1+Math.floor(Math.random()*missionVariables.rescuestation_danger1)+Math.floor(Math.random()*missionVariables.rescuestation_danger2);
				if (danger < 2) {
						danger = 2;
				}
				var enemy = new Array();
				for (var i = 0; i < danger; i++)
					enemy.push(system.addVisualEffect("rrs_witchspace_anomaly",this.ship.position.add(Vector3D.randomDirectionAndLength(15E3))));
				for (i=0;i<enemy.length;i++) {
						if (enemy[i].position.distanceTo(this.ship.position) < 10E3) {
								enemy[i].position = enemy[i].position.add(enemy[i].position.subtract(this.ship.position).direction().multiply(10E3));
						}
				}
				
				var leader = system.shipsWithRole("arafura-mission",this.ship,25E3);
				leader[0].commsMessage("Detecting witchspace anomalies. All [mission_rescuestation_wingname], red alert!");

		}
}
Scripts/rescue_scenario_1b_leader.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Rescue Scenario 1b Leader";
this.description = "AI for the Moray Rescue Leader";

this.revert = function() {
		this.ship.setScript("rescue_scenario_1_leader.js");
		this.ship.switchAI("rescue_scenario_1_leaderAI.plist");
}
Scripts/rescue_scenario_2.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 2"; 
this.description = "This script adds scenario 2 rescue mission."; 

//added background images to mission screens -spara-

this.scenarioID = "2";

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerScenario(this.scenarioID);
}

this.missionAvailableCount = function() {
		return 1;
}

this.missionAvailable = function() {
		if (missionVariables.rescuestation_reputation < -10) {
				return false; // bad reputation
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (Math.random() < 0.5) {
				return true; // often available
		}
		return false;
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_reward = 30;
		missionVariables.rescuestation_system = system.ID;
}

this.rescue_shipDockedWithStation = function (rstation) {
		
		if (rstation.isMainStation && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage == 2) {
				missionVariables.rescuestation_stage = 1000;
		}
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Package delivery needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_2_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Delivery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();

		}
}


this.rescue_shipWillLaunchFromStation = function (rstation) {

}


this.rescue_shipWillExitWitchspace = function() {
		player.consoleMessage("You were supposed to deliver a package before leaving the system!");
		worldScripts["Rescue Stations"].failMission();
}

/* Mission setup */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 2; // only really useful for complete beginners and restoring a damaged reputation
		// nothing special		
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 10; // how can you get this one wrong!
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_system;
}


this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Transferring package",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2_mission_accepted",
													 model: "alloy",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															worldScripts["Rescue Stations"].acceptMission();
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_2_description");
													}
												 );
		}
}

/* Mission functions */

Scripts/rescue_scenario_2a.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 2a"; 
this.description = "This script adds scenario 2 variant A delivery mission."; 

//added background images to mission screens -spara-

this.scenarioID = "2a";


this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("2",this.scenarioID);
}

this.missionAvailable = function() {
		if (missionVariables.rescuestation_reputation < 10) {
				return false; // not enough reputation
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (Math.random() < 0.8) {
				return true; // generally replace if the player's rep is high enough
		}
		return false;
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_reward = 150;
		missionVariables.rescuestation_system = system.ID;
		missionVariables.rescuestation_deadline = clock.seconds+7200; // 2 hours
}

this.rescue_shipDockedWithStation = function (rstation) {

		if (rstation.isMainStation && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage == 3) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 1000;
				} else {
						missionVariables.rescuestation_stage = 1001;
				}
		}
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Package delivery needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_2a_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Delivery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2a_mission_complete",
													 model: "rescue_blackbox",
													 background: "rrsfl_blank_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();

		} else if (missionVariables.rescuestation_stage == 1001) {
				mission.runScreen({title: "You have arrived too late",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2a_mission_toolate",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].failMission();

		}

}

this.rescue_shipWillExitWitchspace = function () {
		worldScripts["Rescue Scenario 2"].rescue_shipWillExitWitchspace();
}

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 10;
		// nothing special		

		worldScripts["Rescue News"].sendNews("rescue_scenario_2a_news",1,0.02);

}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 10; 
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_system;
}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Transferring package",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2a_mission_accepted",
													 model: "rescue_blackbox",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															worldScripts["Rescue Stations"].acceptMission();
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_2a_description");
													}
												 );
		}
}

this.rescue_shipWillLaunchFromStation = function (rstation) {
		if (missionVariables.rescuestation_stage == 2 && rstation.hasRole("rescue_station")) {
				missionVariables.rescuestation_stage = 3;

				var nhunters = 2+worldScripts["Rescue Stations"].dangerScale(128); 

				var hunters = system.addShipsToRoute("rrs-vicious-hunter",nhunters,0.85,"wp");
				for(var i=0;i<hunters.length;i++) {
						hunters[i].switchAI("rescue_player_hunterAI.plist");
						hunters[i].setScript("rrs_player_hunter.js");
						hunters[i].awardEquipment("EQ_FUEL_INJECTION");
						hunters[i].fuel = 7;
//						hunters[i].displayName = hunters[i].name+" (hunter)";
				}

		}

}


/* Mission functions */

Scripts/rescue_scenario_2b.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 2b"; 
this.description = "This script adds scenario 2, variant B solar lab mission."; 

//updated pylon equipment removal -spara-
//added background images to mission screens -spara-

this.scenarioID = "2b";


this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("2",this.scenarioID);
}

this.missionAvailable = function() {
		if (missionVariables.rescuestation_reputation < 0) {
				return false; // not enough reputation
		}
		if (player.ship.missileCapacity == 0) {
				return false; // no point if no missiles can be carried
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (player.credits < 80) {
				return false; // must be able to pay the deposit.
		}
		if (Math.random() < 0.3) {
				return true; // sometimes available
		}
		return false;
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_reward = 75;
		missionVariables.rescuestation_system = system.ID;
		missionVariables.rescuestation_deadline = clock.seconds+14400; // 4 hours
}

this.rescue_shipDockedWithStation = function (rstation) {

		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage == 100) {
				if (player.ship.equipmentStatus("EQ_RRS_SOLAR_MINE") == "EQUIPMENT_OK") {
						if (clock.seconds < missionVariables.rescuestation_deadline) {
								missionVariables.rescuestation_stage = 1000;
						} else {
								missionVariables.rescuestation_stage = 1001;
						}
						this.removeSolarMine();
				} else {
						player.consoleMessage("You seem to have lost the laboratory somewhere.");
						worldScripts["Rescue Stations"].failMission();
				}
		} else if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage < 100 && clock.seconds >= missionVariables.rescuestation_deadline) {
				missionVariables.rescuestation_stage = 1001;
				this.removeSolarMine();
		}
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Portable solar laboratory deployment",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_2b_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices",
														model: "EQ_RRS_SOLAR_MINE",
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward + 80; // repay equipment deposit too

				mission.runScreen({title: "Laboratory returned",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2b_mission_complete",
													 model: "EQ_RRS_SOLAR_MINE",
													 background: "rrsfl_blank_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();

		} else if (missionVariables.rescuestation_stage == 1001) {
				player.credits += 80; // return deposit

				mission.runScreen({title: "Laboratory deadline missed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2b_mission_toolate",
													 background: "rrsfl_bg.png"});
				worldScripts["Rescue Stations"].failMission();

		}

}

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 4;
		// nothing special		
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 10;
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_system;
}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Mission accepted",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_2b_mission_accepted",
													 model: "EQ_RRS_SOLAR_MINE",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															worldScripts["Rescue Stations"].acceptMission();
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_2b_description");
															missionVariables.rescuestation_solarlabavailable = 1;
													}
												 );
		}
}

this.rescue_shipWillLaunchFromStation = function (rstation) {
		if (missionVariables.rescuestation_stage == 2 && rstation.hasRole("rescue_station")) {
				missionVariables.rescuestation_stage = 3;
				

		}

}

this.rescue_solarLabReactionComplete = function() {
		if (missionVariables.rescuestation_stage < 50) {
				missionVariables.rescuestation_stage = 50;
				player.commsMessage("RRS: Solar lab reaction complete. Please collect immediately.");
		}
}

this.rescue_solarLabCollected = function() {
		if (missionVariables.rescuestation_stage == 50) {
				missionVariables.rescuestation_stage = 100;
				player.consoleMessage("RRS Laboratory collected. Return it to the Waystation");
		}
}

this.rescue_solarLabDestroyed = function() {
		player.consoleMessage("RRS Laboratory destroyed. Mission failed.");
		worldScripts["Rescue Stations"].failMission();
}

this.rescue_solarLabDeployed = function() {
		if (missionVariables.rescuestation_stage < 50) {
				missionVariables.rescuestation_stage = 20;
				delete missionVariables.rescuestation_solarlabavailable;
		}
}

this.rescue_populatingSystem = function() {
		if (system.ID == missionVariables.rescuestation_system &&
				missionVariables.rescuestation_stage == 20 && 
				clock.seconds < missionVariables.rescuestation_deadline) {
// then there was a lab left behind. Don't know exactly where, but never mind
				var rpos = system.sun.position.add(system.mainPlanet.position.subtract(system.sun.position).direction().multiply(system.sun.radius*2));
				var lab = system.addShips("rrs_portable_solar_lab",1,rpos,1);
				lab[0].temperature = 0.65;
		}
}

/* Mission functions */

this.removeSolarMine = function() {
	player.ship.removeEquipment("EQ_RRS_SOLAR_MINE");
}

Scripts/rescue_scenario_3.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 3"; 
this.description = "This script adds scenario 3 rescue mission."; 

//added long range map to the mission screens -spara-
//fixed description expand bug -spara-

this.scenarioID = "3";


this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerScenario(this.scenarioID);
}

this.missionAvailableCount = function() {
		if (Math.random() < 0.2) {
				return 1+this.missionAvailableCount();
		} else {
				return 1;
		}
}

this.missionAvailable = function() {

		if (Math.random() > 0.6) {
				return false; // usually available
		}
		if (missionVariables.rescuestation_reputation < 0) {
				return false; // need reasonable reputation
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
/*		if (player.ship.equipmentStatus("EQ_FUEL_SCOOPS") != "EQUIPMENT_OK") {
				return false; // need a fuel scoop
		}
		if (player.ship.cargoSpaceCapacity < 1) {
				return false; // and somewhere to scoop to
		} */
		var nearby = this.targetSystems();
		if (nearby.length < 1) {
				return false; // no suitable nearby systems
		}
		return true;
}

this.targetSystems = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				if (!((other.systemID !== system.info.systemID) && 
						(!other.sun_gone_nova) &&
						(system.info.distanceToSystem(other) > 7) &&
							(system.info.distanceToSystem(other) < 15))) {
						return false;
				} else {
						var route = system.info.routeToSystem(other);
						return (route && route.distance <= 25);
				}
		});
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_startsystem = system.ID;
		missionVariables.rescuestation_startsystem_name = system.name;

		var nearby = this.targetSystems();
		var destination = nearby[Math.floor(nearby.length*Math.random())];

		missionVariables.rescuestation_destsystem = destination.systemID;
		missionVariables.rescuestation_destsystem_name = destination.name;

		var direction = worldScripts["Rescue Stations"].getDirection(system.info,destination);

		missionVariables.rescuestation_destsystem_desc = destination.name+" ("+expandDescription("[rescue_govname_"+destination.government+"]")+", "+Math.round(system.info.distanceToSystem(destination))+" LY "+direction+")";

		var timer = (2.3+Math.random())*(system.info.routeToSystem(destination).time);
		var deadline = clock.seconds+(timer*3600); // routeToSystem is in hours
// picked smallest number of jumps for timer, not quickest, to give a
// little flexibility

		missionVariables.rescuestation_deadline = deadline;
		missionVariables.rescuestation_deadline_text = clock.clockStringForTime(deadline);

		var reward = Math.floor(system.info.routeToSystem(destination).distance * 30);
		missionVariables.rescuestation_reward = reward;


		var danger1 = 0; 
		var danger2 = 0; // no ambush
		if (worldScripts["Rescue Stations"].scenariosWon("3") > 0) { // not the first time
				var ambush = (Math.floor(Math.random()*10))-destination.government;
				if (ambush > 0) { // almost always in Anarchy, down to 20% in Corporate
						danger1 = 2 + worldScripts["Rescue Stations"].dangerScale(512); 
						danger2 = 3 + worldScripts["Rescue Stations"].dangerScale(256); 
						if (destination.government <= 1) {
								danger2++;
								if (destination.government == 0) {
										danger1++;
								}
						}
				}
		}
		missionVariables.rescuestation_danger1 = danger1;
		missionVariables.rescuestation_danger2 = danger2;

}

this.rescue_shipDockedWithStation = function (rstation) {
		
		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_startsystem && missionVariables.rescuestation_stage == 100) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 1000;
				} else {
						missionVariables.rescuestation_stage = 1001;
				}
		}
}

this.rescue_missionScreenOpportunity = function() {
		if (worldScripts["Rescue Stations"].restoreDestination) {
			player.ship.targetSystem = worldScripts["Rescue Stations"].restoreDestination;
			delete worldScripts["Rescue Stations"].restoreDestination;
		}
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Recover black box",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_3_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices_map",
														model: "asteroid",
														background: "rrsfl_blank_bg.png"},
													 worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				var debriefing = "rescue_scenario_3_mission_complete"
/*				if (missionVariables.rescuestation_danger1 > 0) {
						reward += 150;
						missionVariables.rescuestation_reward += 150;
						debriefing = "rescue_scenario_3_mission_complete_danger"
				} */
				player.credits += reward;

				mission.runScreen({title: "Black box recovered",
													screenID: "rrs_mission",
													 model: "rescue_blackbox",
													 messageKey: debriefing,
													 background: "rrsfl_blank_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();
		} else if (missionVariables.rescuestation_stage == 1001) {
				mission.runScreen({title: "Black box recovered",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_3_mission_toolate",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].failMission();
				
		}
}


this.rescue_shipWillLaunchFromStation = function (rstation) {
		if (missionVariables.rescuestation_stage == 2 && system.ID == missionVariables.rescuestation_destsystem && missionVariables.rescuestation_deadline > clock.seconds) {
				this.makeAsteroidField();
				player.consoleMessage("That black box must be somewhere around here.",10);
		}
}


this.rescue_populatingSystem = function() {
		if (missionVariables.rescuestation_stage == 2 && system.ID == missionVariables.rescuestation_destsystem && missionVariables.rescuestation_deadline > clock.seconds) {
				this.makeAsteroidField();
				player.consoleMessage("That black box must be somewhere around here.",10);
		} else if (missionVariables.rescuestation_stage == 2 && missionVariables.rescuestation_deadline <= clock.seconds) {
				player.consoleMessage("You have taken too long to find the black box.",10);			
				worldScripts["Rescue Stations"].failMission();
		}
}

/* Mission setup */

this.missionSuccess = function() {
		mission.unmarkSystem({system: missionVariables.rescuestation_startsystem, name: "RRS"});
		missionVariables.rescuestation_reputation += 10;
		if (missionVariables.rescuestation_danger1 > 0) {
				missionVariables.rescuestation_reputation += 3;
		}

		// nothing special		
}

this.failMission = function () {
		if (missionVariables.rescuestation_stage > 100) {
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		} else {
				mission.unmarkSystem({system: missionVariables.rescuestation_startsystem, name: "RRS"});
		}
		missionVariables.rescuestation_reputation -= 5; 
		if (missionVariables.rescuestation_stage != 1001) {
				missionVariables.rescuestation_reputation -= 5; // bringing it back at all does reduce the penalty
		}
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_deadline_text;
		delete missionVariables.rescuestation_startsystem;
		delete missionVariables.rescuestation_startsystem_name;
		delete missionVariables.rescuestation_destsystem;
		delete missionVariables.rescuestation_destsystem_name;
		delete missionVariables.rescuestation_danger1;
		delete missionVariables.rescuestation_danger2;
		player.ship.removeEquipment("EQ_RRS_CARGO_HOLDER1");
		mission.setInstructions(null, "Rescue Scenario 3");
}


this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} 
		
		else if (choice === "MAP") {
			worldScripts["Rescue Stations"].restoreDestination = player.ship.targetSystem;
			player.ship.targetSystem = missionVariables.rescuestation_destsystem;
				mission.runScreen ({title: "Recover black box",
														screenID: "rrs_mission_map",
														backgroundSpecial: "LONG_RANGE_CHART_QUICKEST"
														},
														worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_missionScreenOpportunity
													);
		}
		
		else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Mission accepted",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_3_mission_accepted",
													 model: "rescue_blackbox",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															mission.markSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
															worldScripts["Rescue Stations"].acceptMission();
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_3_description");
													}
												 );
		}
}

/* Mission functions */

this.makeAsteroidField = function() {
		if (system.shipsWithPrimaryRole("rescue_blackbox").length > 0) {
				return; // already done
		}
		

		var fieldcentre = Vector3D(0,0,0.2+(Math.random()*0.3)).fromCoordinateSystem("wsu");
		fieldcentre.add(Vector3D.random(20E3));
		
		var asteroids = 150;
		var fieldradius = 20E3;
		for (var i=0;i<asteroids;i++) {
				var apos = fieldcentre.add(Vector3D.randomDirectionAndLength(fieldradius));
				system.addShips("asteroid",1,apos,1E3);
		}
		
		var bb = system.addShips("rescue_blackbox",1,fieldcentre,5E3);

		if (missionVariables.rescuestation_danger1 > 0) {
				system.addGroup("rrs_asteroid_ambusher",missionVariables.rescuestation_danger1+Math.floor(Math.random()*missionVariables.rescuestation_danger2),fieldcentre,15E3);
		} else {
				var bbpos = bb[0].position;
				// if there aren't pirates, then there might be a few cargo pods left
				if (Math.random() < 0.75) {
						system.addShips("alloy",1+Math.floor(Math.random()*3),bbpos,300);
				}
				if (Math.random() < 0.5) {
						system.addShips("barrel",1+Math.floor(Math.random()*2),bbpos,300);
				}
		}

}

this.collectBox = function() {
		missionVariables.rescuestation_stage = 100;
		mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		mission.markSystem({system: missionVariables.rescuestation_startsystem, name: "RRS"});
		player.ship.awardEquipment("EQ_RRS_CARGO_HOLDER1");
		mission.setInstructions("Special Cargo: 1 TC Black box.", "Rescue Scenario 3");
}
Scripts/rescue_scenario_3_blackbox.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Scenario 3 Black Box";
this.description = "Scenario 3 Black Box script";

this.shipWasScooped = function (scooper) {
		if (scooper.isPlayer) {
				
				player.consoleMessage("Black box retrieved!",10);

				worldScripts["Rescue Scenario 3"].collectBox();
				
		} else {
				player.consoleMessage("Someone else has reached the black box first.",5);
				worldScripts["Rescue Stations"].failMission();
		}
}

this.shipDied = function() {
		if (missionVariables.rescuestation_stage < 100) {
				player.consoleMessage("The black box has been destroyed.",5);
				worldScripts["Rescue Stations"].failMission();
			
		}
}

this.findPlayer = function() {
		if (player.ship.position.distanceTo(this.ship.position) < 7E3) {
				this.ship.commsMessage("Ping!");
				// pretty much necessary to locate the black box, but it's not just the player's attention it attracts
				var ambushers = system.shipsWithPrimaryRole("rrs_asteroid_ambusher",this.ship,25600);
				for(var i=0;i<ambushers.length;i++) {
						ambushers[i].reactToAIMessage("AMBUSH_IS_GO");
				}
		}
}
Scripts/rescue_scenario_3a.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 3a"; 
this.description = "This script adds scenario 3 variant A rescue mission."; 

//added long range map to the mission screens -spara-
//added background image to mission screens -spara-

this.scenarioID = "3a";


this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("3",this.scenarioID);
}

this.missionAvailableCount = function() {
		return 1;
}

// variant, only needs conditions extra to original
this.missionAvailable = function() {
	
		if (Math.random() < 0.4) {
				return true; // even if it can replace as variant, doesn't always
		}
		if (missionVariables.rescuestation_reputation < 20) {
				return false; // need reasonable reputation
		}
		if (worldScripts["Rescue Stations"].scenariosWon("3") == 0) {
				return false; // can't replace the first mission
		}
		var replacer = Math.floor(worldScripts["Rescue Stations"].scenariosWon("3")/5);
		if (replacer < worldScripts["Rescue Stations"].scenariosWon("3a")) {
				return false; // at most 1 in 5 completed missions
		}
		return false;
}

this.initMissionVariables = function() {
		worldScripts["Rescue Scenario 3"].initMissionVariables();
		missionVariables.rescuestation_danger1 = 0; // never a sidewinder ambush in this variant
}

this.rescue_shipDockedWithStation = function (rstation) {
		worldScripts["Rescue Scenario 3"].rescue_shipDockedWithStation(rstation);
}

this.rescue_missionScreenOpportunity = function() {
		if (worldScripts["Rescue Stations"].restoreDestination) {
			player.ship.targetSystem = worldScripts["Rescue Stations"].restoreDestination;
			delete worldScripts["Rescue Stations"].restoreDestination;
		}
		
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen({title: "Recover black box",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_3_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices_map",
														model: "asteroid",
														background: "rrsfl_blank_bg.png"},
													 worldScripts["Rescue Scenario 3"].missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward * 1.5;
				var debriefing = "rescue_scenario_3a_mission_complete"
				player.credits += reward;

				mission.runScreen({title: "Black box recovered",
													screenID: "rrs_mission",
													 model: "rescue_blackbox",
													 messageKey: debriefing,
													 background: "rrsfl_blank_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();
		} else if (missionVariables.rescuestation_stage == 1001) {
				mission.runScreen({title: "Black box recovered",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_3_mission_toolate",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].failMission();
				
		}
}


this.rescue_shipWillLaunchFromStation = function (rstation) {
		worldScripts["Rescue Scenario 3"].rescue_shipWillLaunchFromStation();
}


this.rescue_populatingSystem = function() {
		if (missionVariables.rescuestation_stage == 2 && system.ID == missionVariables.rescuestation_destsystem && missionVariables.rescuestation_deadline > clock.seconds) {
				this.makeAsteroidField();
				player.consoleMessage("That black box must be somewhere around here.",10);
		} else if (missionVariables.rescuestation_stage == 2 && missionVariables.rescuestation_deadline <= clock.seconds) {
				player.consoleMessage("You have taken too long to find the black box.",10);			
				worldScripts["Rescue Stations"].failMission();
		} else if (missionVariables.rescuestation_stage >= 100 && system.ID != missionVariables.rescuestation_startsystem) {
				this.spawnAssassin();
		}
}

this.rescue_shipExitedWitchspace = function() {
		var assassins = system.shipsWithPrimaryRole("rrs-vicious-hunter",player.ship,25600);
		if (assassins.length > 0) {
				assassins[0].commsMessage("[rescue_scenario_3a_conspirator_target]");
		}
		
}

/* Mission setup */

this.missionSuccess = function() {
		mission.unmarkSystem({system: missionVariables.rescuestation_startsystem, name: "RRS"});
		missionVariables.rescuestation_reputation += 15;

		worldScripts["Rescue News"].sendNews("rescue_scenario_3a_news",2,0.2);

		// nothing special		
}

this.failMission = function () {
		if (missionVariables.rescuestation_stage > 100) {
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		} else {
				mission.unmarkSystem({system: missionVariables.rescuestation_startsystem, name: "RRS"});
		}
		missionVariables.rescuestation_reputation -= 5;
		if (missionVariables.rescuestation_stage != 1001) {
				missionVariables.rescuestation_reputation -= 5; // bringing it back at all does reduce the penalty
		}
}

this.cleanupMission = function() {
		worldScripts["Rescue Scenario 3"].cleanupMission();
}

this.missionOfferDecision = function (choice) {
		worldScripts["Rescue Scenario 3"].missionOfferDecision(choice);
}

/* Mission functions */

this.makeAsteroidField = function() {
		worldScripts["Rescue Scenario 3"].makeAsteroidField();
}

this.collectBox = function() {
		worldScripts["Rescue Scenario 3"].collectBox();
}

this.spawnAssassin = function() {
		var numass = 2+worldScripts["Rescue Stations"].dangerScale(128);

		var assassins = system.addShips("rrs-vicious-hunter",numass,player.ship.position.add(Vector3D.random(14E3),1E3));
		for (var i=0;i<assassins.length;i++) {
				var assassin = assassins[i];
				assassin.target = player.ship;
				assassin.setAI("interceptAI.plist");
		}

}
Scripts/rescue_scenario_3a_blackbox.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Scenario 3a Black Box";
this.description = "Scenario 3 Black Box script";

this.shipWasScooped = function (scooper) {
		if (scooper.isPlayer) {
				
				player.consoleMessage("Black box retrieved!",10);

				worldScripts["Rescue Scenario 3"].collectBox();
				
		} else {
				player.consoleMessage("Someone else has reached the black box first.",5);
				worldScripts["Rescue Stations"].failMission();
		}
}

this.shipDied = function() {
		if (missionVariables.rescuestation_stage < 100) {
				player.consoleMessage("The black box has been destroyed.",5);
				worldScripts["Rescue Stations"].failMission();
			
		}
}

this.findPlayer = function() {
		if (player.ship.position.distanceTo(this.ship.position) < 7E3) {
				this.ship.commsMessage("Ping!");
				// pretty much necessary to locate the black box, but it's not just the player's attention it attracts
				var ambushers = system.shipsWithPrimaryRole("rrs_asteroid_ambusher",this.ship,25600);
				for(var i=0;i<ambushers.length;i++) {
						ambushers[i].reactToAIMessage("AMBUSH_IS_GO");
				}
		}
}
Scripts/rescue_scenario_4.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 4"; 
this.description = "This script adds scenario 4 rescue mission."; 

//added long range map to the mission screens -spara-
//fixed description expand bug -spara-

this.scenarioID = "4";

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerScenario(this.scenarioID);

}

this.missionAvailableCount = function() {
		var mac = Math.floor(Math.sqrt(1+(Math.random()*9))); // probably 1 or 2, rarely 3
		if (mac<1) { return 1; }
		return mac;
}

this.missionAvailable = function() {
		if (missionVariables.rescuestation_reputation < 10) {
				return false; // need some rep to start doing these
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (Math.random() > 0.7) {
				return false; // often available
		}
		var nearby = this.targetSystems();
		if (nearby.length == 0) {
				return false; // nowhere suitable (unlikely!)
		}
		return true;
}

this.targetSystems = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				if (!( (other.systemID !== system.info.systemID) && 
						(!other.sun_gone_nova) &&
						(other.government <= 4) && // communist or less
						(system.info.distanceToSystem(other) > 7) &&
							 (system.info.distanceToSystem(other) < 15))) {
						return false;
				} else {
						var route = system.info.routeToSystem(other);
						return (route && route.distance <= 25);
				}
		});
}


this.initMissionVariables = function() {

		missionVariables.rescuestation_system = system.ID;
		missionVariables.rescuestation_system_name = system.name; 
		var systems = this.targetSystems();
		
		var destsystem = systems[Math.floor(Math.random()*systems.length)];
		
		missionVariables.rescuestation_destsystem = destsystem.systemID;
		missionVariables.rescuestation_destsystem_name = destsystem.name;

		var direction = worldScripts["Rescue Stations"].getDirection(system.info,destsystem);
		missionVariables.rescuestation_destsystem_desc = destsystem.name+" ("+expandDescription("[rescue_govname_"+destsystem.government+"]")+", "+Math.round(system.info.distanceToSystem(destsystem))+" LY "+direction+")";

		var deadline = clock.seconds+(3600*system.info.routeToSystem(destsystem).time*(2.2+Math.random()));
		missionVariables.rescuestation_deadline = deadline;
		missionVariables.rescuestation_deadline_text = clock.clockStringForTime(deadline);

		missionVariables.rescuestation_pilot = randomName()+" "+randomName();
		missionVariables.rescuestation_pilotdesc = randomInhabitantsDescription(false);

		var reward = Math.floor((3*system.info.routeToSystem(destsystem).distance-destsystem.government) * 15);

		missionVariables.rescuestation_reward = reward;
}

this.rescue_shipDockedWithStation = function (rstation) {
		
		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage >= 100) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 1000;
				} else {
						missionVariables.rescuestation_stage = 1001;
				}
		} else if (rstation.isMainStation && system.ID == missionVariables.rescuestation_destsystem && missionVariables.rescuestation_stage < 100) {
				missionVariables.rescuestation_stage = 100;
		}

}

this.rescue_missionScreenOpportunity = function() {
		if (worldScripts["Rescue Stations"].restoreDestination) {
			player.ship.targetSystem = worldScripts["Rescue Stations"].restoreDestination;
			delete worldScripts["Rescue Stations"].restoreDestination;
		}
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Personnel recovery needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_4_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices_map",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Recovery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();
		} else if (missionVariables.rescuestation_stage == 1001) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Recovery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4_mission_toolate",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].failMission();

		} else if (missionVariables.rescuestation_stage == 100) {
				mission.runScreen({title: "Pilot rescued",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4_mission_rescue",
													 model: player.ship.dockedStation.primaryRole,
													 background: "rrsfl_blank_bg.png"});

				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
				mission.markSystem({system: missionVariables.rescuestation_system, name: "RRS"});

				missionVariables.rescuestation_stage = 101;
		}
}


this.rescue_shipWillLaunchFromStation = function (rstation) {

}


this.rescue_shipExitedWitchspace = function() {
		if (missionVariables.rescuestation_stage < 100 && clock.seconds > missionVariables.rescuestation_deadline) {
				player.commsMessage(missionVariables.rescuestation_system_name+" RRS: We've managed to get commercial transport for "+missionVariables.rescuestation_pilot+". Try to be a bit more prompt in future or there's no point hiring you!");
				worldScripts["Rescue Stations"].failMission();
		}

}

/* Mission setup */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 10;
		// nothing special		
}

this.failMission = function () {
		if (missionVariables.rescuestation_stage > 100) {
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		} else {
				mission.unmarkSystem({system: missionVariables.rescuestation_startsystem, name: "RRS"});
		}
		if (missionVariables.rescuestation_stage != 1001) {
				missionVariables.rescuestation_reputation -= 10; // no rep penalty if they were retrieved
		}
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_system;
		delete missionVariables.rescuestation_system_name;
		delete missionVariables.rescuestation_destsystem;
		delete missionVariables.rescuestation_destsystem_name;
		delete missionVariables.rescuestation_destsystem_desc;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_deadline_text;
		delete missionVariables.rescuestation_pilot;
		delete missionVariables.rescuestation_pilotdesc;
}


this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} 
		else if (choice === "MAP") {
			worldScripts["Rescue Stations"].restoreDestination = player.ship.targetSystem;
			player.ship.targetSystem = missionVariables.rescuestation_destsystem;
				mission.runScreen ({title: "Personnel recovery needed",
														screenID: "rrs_mission_map",
														backgroundSpecial: "LONG_RANGE_CHART_QUICKEST"
														},
														worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_missionScreenOpportunity
													);
		}
		else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Good luck",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4_mission_accepted",
													 model: "rescue_station",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															worldScripts["Rescue Stations"].acceptMission();
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_4_description");
													}
												 );
				mission.markSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
				
		}
}

/* Mission functions */

Scripts/rescue_scenario_4a.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 4a"; 
this.description = "This script adds scenario 4a rescue mission."; 

//added long range map to the mission screens -spara-
//removed beacon buoy and added beacon to the base instead -spara-
//fixed description expand bug -spara-
//added background images to mission screens -spara-

this.scenarioID = "4a";

/* Stages:
 * 2: mission accepted
 * 10: base location given
 * 30: base has launched slaver
 * 40: slaver launching pods
 * 41-45: slaver pods collected
 * 100: rescue complete
 * 1000: mission complete
 * 1001: mission completed too late
 */

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("4",this.scenarioID);
}

this.missionAvailable = function() {

		if (Math.random() > 0.6) {
				return false; // often available
		}
		if (worldScripts["Rescue Stations"].scenariosWon("4") == 0) {
				return false; // must complete one base one before any variants start appearing
		}
		if (missionVariables.rescuestation_reputation < 20) {
				return false; // need some rep to start doing these
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (player.ship.equipmentStatus("EQ_FUEL_SCOOPS") != "EQUIPMENT_OK") {
				return false; // needs fuel scoops, secretly
		}
		if (player.ship.equipmentStatus("EQ_ADVANCED_COMPASS") != "EQUIPMENT_OK") {
				return false; // needs advanced compass, secretly
		}
		var nearby = this.targetSystems();
		if (nearby.length == 0) {
				return false; // nowhere suitable (rare!)
		}
		return true;
}

this.targetSystems = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				if (!((other.systemID !== system.info.systemID) && 
						(!other.sun_gone_nova) &&
						(other.government <= 1) && // feudal or less
							(system.info.distanceToSystem(other) < 15))) {
						return false;
				} else {
						var route = system.info.routeToSystem(other);
						return (route && route.distance <= 25);
				}
		});
}


this.initMissionVariables = function() {

		missionVariables.rescuestation_system = system.ID;
		missionVariables.rescuestation_system_name = system.name; 
		var systems = this.targetSystems();
		
		var destsystem = systems[Math.floor(Math.random()*systems.length)];
		
		missionVariables.rescuestation_destsystem = destsystem.systemID;
		missionVariables.rescuestation_destsystem_name = destsystem.name;

		var direction = worldScripts["Rescue Stations"].getDirection(system.info,destsystem);
		missionVariables.rescuestation_destsystem_desc = destsystem.name+" ("+expandDescription("[rescue_govname_"+destsystem.government+"]")+", "+Math.round(system.info.distanceToSystem(destsystem))+" LY "+direction+")";

		var deadline = clock.seconds+(3600*system.info.routeToSystem(destsystem).time*(2.2+Math.random()));
		missionVariables.rescuestation_deadline = deadline;
		missionVariables.rescuestation_deadline_text = clock.clockStringForTime(deadline);

		missionVariables.rescuestation_pilot = randomName()+" "+randomName();
		missionVariables.rescuestation_pilotdesc = randomInhabitantsDescription(false);

		var reward = Math.floor((3*system.info.routeToSystem(destsystem).distance-destsystem.government) * 15);

		missionVariables.rescuestation_reward = reward;


		var danger1 = 2+worldScripts["Rescue Stations"].dangerScale(256); 
		var danger2 = 3+worldScripts["Rescue Stations"].dangerScale(128);

		missionVariables.rescuestation_danger1 = danger1;
		missionVariables.rescuestation_danger2 = danger2;

}

this.rescue_shipDockedWithStation = function (rstation) {

		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage >= 100) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 1000;
				} else {
						missionVariables.rescuestation_stage = 1001;
				}
		} else if (rstation.isMainStation && system.ID == missionVariables.rescuestation_destsystem && missionVariables.rescuestation_stage < 10) {
				missionVariables.rescuestation_stage = 10;
		} else if (missionVariables.rescuestation_stage >= 40 && missionVariables.rescuestation_stage < 50) {
				if (rstation.isMainStation || rstation.hasRole("rescue_station")) {
						var rescued = missionVariables.rescuestation_stage-40;
						if (rescued == 0) {
								player.consoleMessage("You're out of leads. "+missionVariables.rescuestation_pilot+" is either dead or MIA.");
								worldScripts["Rescue Stations"].failMission();
						} else if (Math.random()*5 < rescued) {
								missionVariables.rescuestation_stage = 90; // rescued!
								player.credits += rescued*50;
								missionVariables.rescuestation_reputation += rescued;
						} else {
								missionVariables.rescuestation_stage = 80; // missed their pod
								player.credits += rescued*50;
								missionVariables.rescuestation_reputation += rescued*5;
								// going to get hit for -30 for failing, so give some mitigation for doing roughly the right thing
						}
						worldScripts["Rescue News"].sendNews("rescue_scenario_4a_news",0,0.02*rescued); // maybe someone famous was rescued?


						missionVariables.rescuestation_reward2 = rescued*50;

				}
		}

}

this.rescue_missionScreenOpportunity = function() {
		if (worldScripts["Rescue Stations"].restoreDestination) {
			player.ship.targetSystem = worldScripts["Rescue Stations"].restoreDestination;
			delete worldScripts["Rescue Stations"].restoreDestination;
		}
		var rstation = player.ship.dockedStation;
		if (rstation.hasRole("rrs_slaverbase")) {
				mission.runScreen ({title: "That was a bad idea",
														screenID: "rrs_mission",
														messageKey: "rescue_slaverbase_eject",
														model: "rrs_slaverbase",
														background: "rrsfl_blank_bg.png"},
													 this.slaverEjectPlayer
													);
		} else if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Personnel recovery needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_4a_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices_map",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Recovery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4a_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();
		} else if (missionVariables.rescuestation_stage == 1001) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Recovery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4a_mission_toolate",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].failMission();

		} else if (missionVariables.rescuestation_stage == 10) {
				mission.runScreen({title: "Bad news",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4a_mission_contacts",
													 model: "police",
													 background: "rrsfl_blank_bg.png"});

				this.markSlavers();
				worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_4a_description");
				
				missionVariables.rescuestation_stage = 11;
		} else if (missionVariables.rescuestation_stage == 80) {
				if (rstation.hasRole("rescue_station")) {
						var mmodel = "rescue_station";
				} else {
						var mmodel = "police";
				}
				mission.runScreen({title: "Mission failed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4a_mission_partfail",
													 model: mmodel,
													 background: "rrsfl_blank_bg.png"});

				worldScripts["Rescue Stations"].failMission();
		} else if (missionVariables.rescuestation_stage == 90) {
				if (rstation.hasRole("rescue_station")) {
						var mmodel = "rescue_station";
				} else {
						var mmodel = "police";
				}
				mission.runScreen({title: "Pilot rescued!",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4a_mission_rescued1",
													 model: mmodel,
													 background: "rrsfl_blank_bg.png"});
				if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system) {
						if (clock.seconds < missionVariables.rescuestation_deadline) {
								missionVariables.rescuestation_stage = 1000;
						} else {
								missionVariables.rescuestation_stage = 1001;
						}
				} else {
						missionVariables.rescuestation_stage = 91;
				}
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		} else if (missionVariables.rescuestation_stage == 91) {
				mission.runScreen({title: "Pilot rescued!",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4a_mission_rescued2",
													 model: player.ship.dockedStation.primaryRole,
													 background: "rrsfl_blank_bg.png"});

// in case the home station is the first one visited
				if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system) {
						if (clock.seconds < missionVariables.rescuestation_deadline) {
								missionVariables.rescuestation_stage = 1000;
						} else {
								missionVariables.rescuestation_stage = 1001;
						}
				} else {
						missionVariables.rescuestation_stage = 100;
						mission.markSystem({system: missionVariables.rescuestation_system, name: "RRS"});
				}
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});

		}

}


this.rescue_populatingSystem = function (rstation) {
		if (system.ID == missionVariables.rescuestation_destsystem) {
				this.addSlaverBase();
		}
}


this.rescue_shipExitedWitchspace = function() {
		if (missionVariables.rescuestation_stage < 10 && clock.seconds > missionVariables.rescuestation_deadline) {
				player.commsMessage(missionVariables.rescuestation_system_name+" RRS: We've just received news that "+missionVariables.rescuestation_pilot+" has been captured by slavers and taken out of the system. Return to base: we'll get someone more reliable to track them down.");
				worldScripts["Rescue Stations"].failMission();
		}

}

/* Mission setup */

this.missionSuccess = function() {
		mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		mission.unmarkSystem({system: missionVariables.rescuestation_system, name: "RRS"});
		missionVariables.rescuestation_reputation += 10;
		// nothing special		
}

this.failMission = function () {
		if (missionVariables.rescuestation_stage < 100) {
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		} else {
				mission.unmarkSystem({system: missionVariables.rescuestation_system, name: "RRS"});
		}
		if (missionVariables.rescuestation_stage != 1001) {
				missionVariables.rescuestation_reputation -= 30; // really bad
		}
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_reward2;
		delete missionVariables.rescuestation_system;
		delete missionVariables.rescuestation_system_name;
		delete missionVariables.rescuestation_destsystem;
		delete missionVariables.rescuestation_destsystem_name;
		delete missionVariables.rescuestation_destsystem_desc;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_deadline_text;
		delete missionVariables.rescuestation_pilot;
		delete missionVariables.rescuestation_pilotdesc;
		delete missionVariables.rescuestation_danger1;
		delete missionVariables.rescuestation_danger2;
		for (var i = 1; i <= 5; i++)
			player.ship.removeEquipment("EQ_RRS_CARGO_HOLDER" + i);
		mission.setInstructions(null, "Rescue Scenario 4a");
}


this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		}
		else if (choice === "MAP") {
			worldScripts["Rescue Stations"].restoreDestination = player.ship.targetSystem;
			player.ship.targetSystem = missionVariables.rescuestation_destsystem;
				mission.runScreen ({title: "Personnel recovery needed",
														screenID: "rrs_mission_map",
														backgroundSpecial: "LONG_RANGE_CHART_QUICKEST"
														},
														worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_missionScreenOpportunity
													);
		}		
		 else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Good luck",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4_mission_accepted",
													 model: "rescue_station",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															worldScripts["Rescue Stations"].acceptMission();
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_4_description");
													}
												 );
				mission.markSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
				
		}
}

/* Mission functions */


this.addSlaverBase = function() {
		
				var pos = Vector3D(0, 0, 0.5).fromCoordinateSystem("wpu");
				var xrange = Math.random();
				var yrange = Math.sqrt(1-(xrange*xrange));
				if (Math.random() < 0.5) { xrange = -xrange; }
				if (Math.random() < 0.5) { yrange = -yrange; }
				var distance = 100E3+(Math.random()*100E3);
				var sbpos = pos.add([xrange*distance,yrange*distance,0]);
				
				var slaverbase = system.addShips("rrs_slaverbase",1,sbpos,20E3);
				slaverbase[0].orientation = Quaternion.random();

				var pirates = system.addGroup("pirate",missionVariables.rescuestation_danger1+Math.floor(Math.random()*missionVariables.rescuestation_danger2),slaverbase[0].position,10E3);

				for (var i=0;i<pirates.ships.length;i++) {
						pirates.ships[i].setScript("rescue_scenario_4a_sbdef.js");
						pirates.ships[i].switchAI("rescue_scenario_4a_sbdefAI.plist");
						pirates.ships[i].primaryRole = "sbdefender";
						pirates.ships[i].bounty += Math.floor(Math.random()*50);
				}
				if (missionVariables.rescuestation_stage > 10) {
						this.markSlavers();
				}

}

this.markSlavers = function() {
		var getsb = system.shipsWithRole("rrs_slaverbase");
		getsb[0].beaconCode = "Slaver Base";
}

this.slaverEjectPlayer = function(choice) {
		player.ship.energy = 10;
		player.ship.forwardShield = 0;
		player.ship.aftShield = 0;
		player.ship.launch();
		rstation.commsMessage("And stay out!");
}
Scripts/rescue_scenario_4a_sbdef.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 4a Slaver Defence";
this.description = "Rescue Scenario 4a: defense ship script";

this.baseCoords = function() {
		var getsb = system.shipsWithRole("rrs_slaverbase");
		if (getsb.length > 0) {
				var buoypos = getsb[0].position.add(getsb[0].vectorForward.multiply(5E3));
				this.ship.savedCoordinates = buoypos;
				this.ship.reactToAIMessage("FOUND_BASE");
		} else {
				this.ship.reactToAIMessage("NO_BASE");
		}
}

this.shipTargetLost = function() {
		if (this.ship.AI == "interceptAI.plist") {
				this.ship.exitAI();
		}
}
Scripts/rescue_scenario_4a_slaver.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 4a Slave Trader";
this.description = "Rescue Scenario 4a: slave trader script";

this.storedslaves = 5;
this.ejectiontimer = null;
this.$plotHint = true;

this.checkEnergy = function() {
		if (this.ship.energy < this.ship.maxEnergy/3) {
				this.ejectSlaves();
		}
}

this.ejectSlaves = function() {
		if (this.ejectiontimer == null) {
				this.ejectiontimer = new Timer(this,this.ejectSlave,1,2);
				this.ship.commsMessage("Take my cargo, but let me go!");
		} else if (this.storedslaves == 0) {
				this.ship.reactToAIMessage("JUMP_AWAY");
		}
}		

this.shipDied = function() {
		if (missionVariables.rescuestation_stage == 30) {
				// destroyed before could eject cargo
				this.ship.spawn("rrs_slaver_pod",2); // might get lucky
		} else if (missionVariables.rescuestation_stage < 35) {
				this.ship.spawn("rrs_slaver_pod",1); // might get lucky
		} else if (missionVariables.rescuestation_stage < 40) {
				missionVariables.rescuestation_stage = 40;
		}
}

this.ejectSlave = function() {
	if (this.storedslaves > 0) {
		if (this.$plotHint) {
			player.consoleMessage(missionVariables.rescuestation_pilot + " must be in one of those pods! Collect them and return to " + missionVariables.rescuestation_system_name + " RRS.");
			this.$plotHint = false;
		}
		//this.ship.speed = 0;
		this.ship.ejectSpecificItem("rrs_slaver_pod");
		//this.ship.speed = this.ship.maxSpeed;
		if (missionVariables.rescuestation_stage < 40) //don't add, if collecting is already in process.
			missionVariables.rescuestation_stage++;
		this.storedslaves--;
	} else {
			this.ejectiontimer.stop();
			if (missionVariables.rescuestation_stage < 40) {
					missionVariables.rescuestation_stage = 40;
			}
			this.ship.reactToAIMessage("JUMP_AWAY");
	}
}

this.leaveSystem = function() {
		this.ship.exitSystem();
}
Scripts/rescue_scenario_4a_slaverbase.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 4a Slaver Base";
this.description = "Rescue Scenario 4a: base AI and ship launching";

this.underAttack = function() {
		var defenders = system.countShipsWithRole("sbdefender",this.ship,25600);
		if (defenders == 0 || this.ship.energy < this.ship.maxEnergy/3) {
				if (worldScripts["Rescue Stations"].missionActive()) {
						if (missionVariables.rescuestation_stage < 30) {
								this.ship.launchShipWithRole("rrs-slavetrader",true);
								this.ship.commsMessage("Abandon ship!");
								// emergency launch before the station is destroyed!
								missionVariables.rescuestation_stage = 30;

						}
				}
		}
}

this.stationLaunchedShip = function(whom) {
		if (whom != player.ship) {
				whom.bounty += 5+Math.floor(5*Math.random());
				whom.bounty = whom.bounty * 2;
		}
}
Scripts/rescue_scenario_4a_slaverpod.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 4a Slave Pod";
this.description = "Rescue Scenario 4a: slave pod script";

this.shipWasScooped = function(scooper) {
	if (scooper == player.ship) {
		if (missionVariables.rescuestation_stage < 41) {
				missionVariables.rescuestation_stage = 41;
		} else if (missionVariables.rescuestation_stage < 45) {
				missionVariables.rescuestation_stage++;
		}
		var podNumber = missionVariables.rescuestation_stage - 40;
		player.ship.awardEquipment("EQ_RRS_CARGO_HOLDER" + podNumber);
		mission.setInstructions("Special Cargo: " + podNumber + " TC Rescued slaves.", "Rescue Scenario 4a");
		player.consoleMessage("1 TC Rescued slaves");
	}
}
Scripts/rescue_scenario_4b.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 4b"; 
this.description = "This script adds scenario 4b rescue mission."; 

//added background image to mission screens -spara-

this.scenarioID = "4b";

this.agenttimer = undefined;
this.agenttimer2 = undefined;

/* Stages:
 * 2: mission accepted
 * 10: meet with agent
 * 20: met with agent
 * 30: reached astromine (deadline applies)
 * 40: waiting for hacking
 * 50: roster hacked
 * 70: player launches
 * 80: miner launches
 * 90: system ships go hostile (will need a non-following AI)
 * 100: reached home system
 * 900: miner docks with RRS
 * 1000: mission complete
 * 1001: redock with astromine after launching (fails, badly)
 * 1002: arrive at astromine too late (already dead)
 */

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("4",this.scenarioID);
}

this.missionAvailable = function() {

		if (worldScripts["Rescue Stations"].scenariosWon("4a") == 0) {
				return false; // must complete one normal slave rescue first
		}
		if (missionVariables.rescuestation_reputation < 80) {
				return false; // Tier 4 Contractor
		}
		if (worldScripts["Rescue Stations"].scenariosTried("4b") > worldScripts["Rescue Stations"].scenariosTried("4a")*10) {
				return false; // relatively rare
		}
		if (player.ship.equipmentStatus("EQ_RRS_FLIGHTFORM") != "EQUIPMENT_OK") {
				return false; // needs formation flight computer, secretly
		}
		var nearby = this.targetSystems();
		if (nearby.length == 0) {
				return false; // nowhere suitable (often the case)
		}
		if (Math.random() < 0.3) {
				return true; // sometimes available in that case
		}
		return false;
}

this.targetSystems = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				return (other.systemID !== system.info.systemID) && 
						(!other.sun_gone_nova) &&
						(other.government == 4) && // communist
						(system.info.distanceToSystem(other) < 7);
		});
}

this.initMissionVariables = function() {

		missionVariables.rescuestation_system = system.ID;
		missionVariables.rescuestation_system_name = system.name; 
		var systems = this.targetSystems();
		
		var destsystem = systems[Math.floor(Math.random()*systems.length)];
		
		missionVariables.rescuestation_destsystem = destsystem.systemID;
		missionVariables.rescuestation_destsystem_name = destsystem.name;
		
		var deadline = clock.seconds+(3600*system.info.routeToSystem(destsystem).time*(1.5+Math.random()));
		missionVariables.rescuestation_deadline = deadline;

		missionVariables.rescuestation_pilot = randomName()+" "+randomName();
		missionVariables.rescuestation_pilotdesc = randomInhabitantsDescription(false);

		missionVariables.rescuestation_agent = randomName()+" "+randomName();
		missionVariables.rescuestation_agentdesc = randomInhabitantsDescription(false);

		missionVariables.rescuestation_reward = 1250;
}

this.rescue_shipDockedWithStation = function (rstation) {
		var stage = missionVariables.rescuestation_stage;
		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system && stage >= 900) {
				missionVariables.rescuestation_stage = 1000;
		} else if (rstation.isMainStation && system.ID == missionVariables.rescuestation_destsystem && stage < 10) {
				missionVariables.rescuestation_stage = 10;
		} else if (rstation.hasRole("rrs_astromine") && stage >= 20 && stage < 30) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 30;
				} else {
						missionVariables.rescuestation_stage = 1002;
				}
		} else if (rstation.hasRole("rrs_astromine") && stage > 70) {
				missionVariables.rescuestation_stage = 1001;
		}
}

this.rescue_missionScreenOpportunity = function() {
		var stage = missionVariables.rescuestation_stage;

		if (stage == 1) {
				mission.runScreen ({title: "Urgent assistance needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_4b_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (stage == 10) {
				mission.runScreen ({title: "The situation is bad",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_4b_meetagent",
														model: "rrs_astromine",
														background: "rrsfl_blank_bg.png"});
				missionVariables.rescuestation_stage = 20;
		} else if (stage == 30) {
				mission.runScreen ({title: "Be ready to leave fast",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_4b_splitup",
														model: "rrs_astromine",
														background: "rrsfl_blank_bg.png"});
				missionVariables.rescuestation_stage = 40;
				this.agenttimer = clock.seconds
				// start timer to set stage to 50
		} else if (stage == 50) {
				mission.runScreen ({title: "Here's the plan",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_4b_timetogo",
														model: "rrs_astromine",
														background: "rrsfl_blank_bg.png"});
				missionVariables.rescuestation_stage = 60;
		} else if (stage == 1000) {
				player.credits += missionVariables.rescuestation_reward;
				mission.runScreen({title: "Recovery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4b_mission_complete",
													 background: "rrsfl_bg.png"});
				worldScripts["Rescue Stations"].missionSuccess();
		} else if (stage == 1001) {
				mission.runScreen({title: "What are we doing back here?",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4b_mission_gowrong",
													 background: "rrsfl_bg.png"});
				missionVariables.rescuestation_reputation -= 5; // seriously bad
				worldScripts["Rescue Stations"].failMission();
		} else if (stage == 1002) {
				mission.runScreen({title: "We're too late",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4b_mission_toolate",
													 background: "rrsfl_bg.png"});
				worldScripts["Rescue Stations"].failMission();
		}

}

this.rescue_guiScreenChanged = function(to, from) {
		if (player.ship.dockedStation && player.ship.dockedStation.hasRole("rrs_astromine")) {
				if (missionVariables.rescuestation_stage == 40) {
						if (this.agenttimer + 60 < clock.seconds) {
								missionVariables.rescuestation_stage = 50;
						}
				}
				if (missionVariables.rescuestation_stage == 50) {
						if (guiScreen == to && (from == "GUI_SCREEN_STATUS" || to == "GUI_SCREEN_STATUS")) {
								this.rescue_missionScreenOpportunity();
						}
				}
		}
}

this.rescue_shipWillLaunchFromStation = function(rstation) {
		if (missionVariables.rescuestation_stage == 60) {
				missionVariables.rescuestation_stage = 70;
				system.addShips("rrs_astroguard",3,rstation.position,20E3);
				this.agenttimer = new Timer(this,rstation.script.launchRRS,30);
				this.agenttimer2 = new Timer(this,rstation.script.launchDefence,65);
		}
}

this.rescue_populatingSystem = function (rstation) {
		if (system.ID == missionVariables.rescuestation_destsystem) {
				this.addAstroMine();
		}
}

/* Mission setup */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 20;
		missionVariables.rescuestation_noentry = missionVariables.rescuestation_destsystem;
		missionVariables.rescuestation_noentrytime = clock.days;
		// special mission
}

this.failMission = function() {
		missionVariables.rescuestation_reputation -= 10;
		// special mission
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_system;
		delete missionVariables.rescuestation_system_name;
		delete missionVariables.rescuestation_destsystem;
		delete missionVariables.rescuestation_destsystem_name;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_pilot;
		delete missionVariables.rescuestation_pilotdesc;
		delete missionVariables.rescuestation_agent;
		delete missionVariables.rescuestation_agentdesc;
}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Good luck",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_4b_mission_accepted",
													 model: "rescue_station",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															worldScripts["Rescue Stations"].acceptMission();
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_4b_description");
													}
												 );
				mission.markSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
				
		}
}


/* Mission functions */

this.agentHacker = function() {
		if (missionVariables.rescuestation_stage < 50) {
				missionVariables.rescuestation_stage = 50;
		}
}

this.addAstroMine = function() {
		
		var ampos = system.mainPlanet.position.add(system.mainPlanet.position.subtract(system.sun.position));
		system.addShips("rrs_astromine",1,ampos,5E3);
		system.addShips("asteroid",30,ampos,40E3);

}
Scripts/rescue_scenario_4b_astromine.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 4b Astromine";

// because of the way we call these two functions, this.ship doesn't work

this.launchRRS = function() {
		var ship = system.shipsWithRole("rrs_astromine")[0];
		if (missionVariables.rescuestation_stage == 70) {
				ship.launchShipWithRole("rrs_astrominer");
				missionVariables.rescuestation_stage = 80;
		}
}

this.launchDefence = function() {
		var ship = system.shipsWithRole("rrs_astromine")[0];
		ship.commsMessage("Miner, you are off course. Return to your assigned task or be destroyed!");
		if (missionVariables.rescuestation_stage >= 80) {
				var a = system.shipsWithRole("rrs_astrominer",ship,25600);
				if (a.length > 0) {
						ship.target = a[0];
						var police = system.shipsWithRole("rrs_astroguard",ship,25600);
						for (var i=0;i<police.length;i++) {
								police[i].target = a[0];
								police[i].setAI("interceptAI.plist");
						}
				}
		}
}
Scripts/rescue_scenario_4b_astrominer.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 4b Astrominer";

//changed naming to match random shipnames style. -spara-

this.shipLaunchedFromStation = function() {
		player.consoleMessage("Tight-beam: Follow us");
		this.ship.commsMessage("Acknowledged.");
}

this.shipExitedWormhole = function() {
		this.ship.bounty = 0;
}
this.shipWillEnterWormhole = function() {
		this.ship.bounty = 0;
}

this.shipDied = function(whom,why) {
		if (whom == player.ship) {
				missionVariables.rescuestation_reputation -= 100;
				player.commsMessage(missionVariables.rescuestation_agent+": You did what?! Well, I hope it was worth the credits.");
		} else if (why == "removed") {
				player.commsMessage(missionVariables.rescuestation_agent+": Looks like they weren't able to follow us");
		}
		player.consoleMessage("Their escape craft has been destroyed");
		worldScripts["Rescue Stations"].failMission();
}

this.shipTakingDamage = function(amount,whom,type) {
		if (this.ship.energy > 0) {
				this.ship.commsMessage("Help!");
		}
}

this.shipDockedWithStation = function(station) {
		missionVariables.rescuestation_stage = 900;
		
		player.commsMessage("RRS: They're safe. Dock when ready.");
}

this.findPlayer = function() {
		if (this.ship.position.distanceTo(player.ship.position) < 25000) {
				this.ship.savedCoordinates = player.ship.position;
				this.ship.reactToAIMessage("TARGET_FOUND");
		} else {
				this.ship.reactToAIMessage("NOTHING_FOUND");
		}
}

this.decideSystem = function() {
		this.ship.displayName = this.ship.displayName + ": " + missionVariables.rescuestation_pilot;
		if (system.government == 4) {
				this.ship.reactToAIMessage("FIRST_SYSTEM");
				//this.ship.displayName = missionVariables.rescuestation_pilot+" (escaping)";
		} else {
				this.ship.reactToAIMessage("SECOND_SYSTEM");
				//this.ship.displayName = missionVariables.rescuestation_pilot+" (escaped)";
		}
}

this.getRRSLocation = function() {
		var rrs = system.shipsWithRole("rescue_station",this.ship);
		if (rrs.length == 0) {
				var location = system.mainStation.position;
		} else {
				var location = rrs[0].position;
		}
		this.ship.savedCoordinates = location;
}



this.autopilotModeReady = function() {
		this.autopilotwilling = 1;
}

this.autopilotModeOffline = function() {
		this.autopilotwilling = 0;
}

this.autopilotContinue = function() {
		worldScripts["Rescue Autopilot"].autopilotStep(this.ship);
}
Scripts/rescue_scenario_5.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 5"; 
this.description = "This script adds scenario 5 rescue mission."; 

//added background images to mission screens -spara-
//changed naming scheme -spara-

this.scenarioID = "5";



this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerScenario(this.scenarioID);
}

this.missionAvailableCount = function() {
		return 1;
}

this.missionAvailable = function() {
		if (missionVariables.rescuestation_reputation < 10) {
				return false; // insufficient reputation
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (Math.random() < 0.2) {
				return true; // rarely available
		}
		return false;
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_reward = 250;
		missionVariables.rescuestation_system = system.ID;
		missionVariables.rescuestation_shipname = expandDescription("[rescue_random_shipname]");
}

this.rescue_shipDockedWithStation = function (rstation) {
		
		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage == 100) {
				missionVariables.rescuestation_stage = 1000;
		} else {
				if (missionVariables.rescuestation_stage > 1) {
						if (missionVariables.rescuestation_stage < 1000) {
								player.commsMessage("You have docked before the rescue mission was complete. You will not be paid for this breach of contract!",7);
								worldScripts["Rescue Stations"].failMission();
						}
				}
		}
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Emergency escort needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_5_mission_available",
														choicesKey: "rescue_scenario_urgent_mission_choices",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Escort mission completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_5_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();

		}
}

this.rescue_shipWillLaunchFromStation = function (rstation) {
		if (missionVariables.rescuestation_stage == 2 && rstation.hasRole("rescue_station")) {

				var adddir = Vector3D.randomDirection();
				while (adddir.dot(rstation.vectorForward) < -0.5) {
						adddir = Vector3D.randomDirection();
				}
				
				var tpos = rstation.position.add(adddir.multiply(15E3));
				var rpos = rstation.position.add(adddir.multiply(4E3));
				var ppos = rstation.position.add(adddir.multiply(25E3));

				var freighter = system.addShips("rescue_freighter",1,tpos,1E3);
				freighter[0].target = rstation;
				freighter[0].setAI("rescue_scenario_5_dockingAI.plist");
				freighter[0].setScript("rescue_scenario_5_freighter.js");
				freighter[0].displayName = freighter[0].name + ": " + missionVariables.rescuestation_shipname;

			
				var danger = 4+worldScripts["Rescue Stations"].dangerScale(128);

				var pirates = system.addGroup("pirate",danger,ppos,5E3);
				for(var i=0;i<pirates.ships.length;i++) {
						pirates.ships[i].setScript("rescue_scenario_5_pirate.js");
						if (pirates.ships[i].escorts) {
								for (var j=0;j<pirates.ships[i].escorts.length;j++) {
										pirates.ships[i].escorts[j].setScript("rescue_scenario_5_pirate.js");
								}
						}
				}
				
				var escorts = freighter[0].escorts;
				for (var i=0;i<escorts.length;i++) {
						escorts[i].switchAI("route1patrolAI.plist");
						escorts[i].target = pirates[Math.floor(Math.random()*pirates.length)];
						escorts[i].setAI("interceptAI.plist");
				}
				
				var defense = system.addShips("rrs-escort",2+Math.floor(Math.random()*2),rpos,2E3);
				for (var i=0;i<defense.length;i++) {
						defense[i].switchAI("route1patrolAI.plist");
						defense[i].target = pirates[Math.floor(Math.random()*pirates.length)];
						defense[i].setAI("interceptAI.plist");
				}


				missionVariables.rescuestation_stage = 3;
		}

}

this.rescue_shipWillExitWitchspace = function() {
		if (missionVariables.rescuestation_stage < 100) {
				player.consoleMessage("You have abandoned the rescue mission");
				worldScripts["Rescue Stations"].failMission();
		}
}



/* Mission functions */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 10;

		worldScripts["Rescue News"].sendNews("rescue_scenario_5_news",3,0.05);
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 5; // easy to fail through no fault of own
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_system;
		delete missionVariables.rescuestation_shipname;
}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Downloading mission data",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_5_mission_accepted",
													 choicesKey: "rescue_scenario_urgent_mission_launch",
													 model: "rrs-escort",
													 background: "rrsfl_blank_bg.png"},
													worldScripts["Rescue Scenario 5"].missionOfferAccepted
												 );
		}
}

this.missionOfferAccepted = function (choice) {
		worldScripts["Rescue Stations"].acceptMission();
		worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_5_description");
		player.ship.fuel = 7;
		player.ship.launch();
}
Scripts/rescue_scenario_5_freighter.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 5 Freighter";

this.lastdamagecomplaint = 0;

this.shipDied = function(whom,why) {
		this.ship.commsMessage("[rescue_argh]");
		var rstation = system.shipsWithPrimaryRole("rescue_station",player.ship,25600);
		if (rstation.length > 0) {
				rstation[0].commsMessage("The [mission_rescuestation_shipname] has been destroyed. Clear the pirates then return to base.");
//				rstation[0].reactToAIMessage("DOCKING_ABORTED");
		}
		worldScripts["Rescue Stations"].failMission();

		if (whom == player.ship) {
				missionVariables.rescuestation_reputation -= 20;
		}

}

this.shipWillDockWithStation = function(station) {
		station.commsMessage("The [mission_rescuestation_shipname] has docked safely. Contractors may dock when ready to be paid.");
		missionVariables.rescuestation_stage = 100;
}

this.shipTakingDamage = function(amount,whom,type) {
		if (this.ship.energy > 0) {
				if (this.lastdamagecomplaint+10 < clock.seconds) {
						this.lastdamagecomplaint = clock.seconds;
						if (this.ship.energy > this.ship.maxEnergy/4) {
								this.ship.commsMessage("[rescue_underfire]");
						} else {
								this.ship.commsMessage("[rescue_underheavyfire]");
						}
				}				
		}
}


this.getDC = function() {
		var dc = this.ship.target.position.add(this.ship.target.vectorForward.multiply(3E3));
		this.ship.savedCoordinates = dc;
		this.ship.reactToAIMessage("CORRIDOR_POSITION");
}

this.getDB = function() {
		var db = this.ship.target.position;
		this.ship.savedCoordinates = db;
}
Scripts/rescue_scenario_5_pirate.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 5 Raider";

this.shipDied = function(whom,why) {
// because we replace the standard Thargoid shipscript
		if (this.ship.isThargoid) {
				this.ship.commsMessage(expandDescription("[thargoid_curses]"));
		}

		if (whom == player.ship && missionVariables.rescuestation_stage < 100 && missionVariables.rescuestation_stage > 0) {
				missionVariables.rescuestation_reward += 50;
				if (Math.random() < 0.3) {
						var rstation = system.shipsWithPrimaryRole("rescue_station",player.ship,25600);
						if (rstation.length > 0) {
								rstation[0].commsMessage("[rescue_goodshot]");
						}
				}
		}
}
Scripts/rescue_scenario_5a.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 5a"; 
this.description = "This script adds variant 5A rescue mission ."; 

//added background images to mission screens -spara-
//naming tweaks -spara-

this.scenarioID = "5a";
this.stagetimer = null;
this.notifytimer = null;

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("5",this.scenarioID);
}


this.missionAvailable = function() {
		if (missionVariables.rescuestation_reputation < 20) {
				return false; // insufficient reputation
		}
		if (worldScripts["Rescue Stations"].scenariosWon("5a") > worldScripts["Rescue Stations"].scenariosWon("5")) {
				return false; // not too many
		}
		if (Math.random() < 0.4) {
				return true; // often replaces
		}
		return false;
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_reward = 350;
		missionVariables.rescuestation_system = system.ID;
		missionVariables.rescuestation_shipname = expandDescription("[rescue_wingnames]");
}

this.rescue_shipDockedWithStation = function (rstation) {
		
		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_system && missionVariables.rescuestation_stage == 100) {
				missionVariables.rescuestation_stage = 1000;
		} else {
				if (missionVariables.rescuestation_stage > 1) {
						if (missionVariables.rescuestation_stage < 1000) {
								player.commsMessage("You have docked before the rescue mission was complete. You will not be paid for this breach of contract!",7);
								worldScripts["Rescue Stations"].failMission();
						}
				}
		}
}

this.rescue_missionScreenOpportunity = function() {
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Emergency escort needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_5a_mission_available",
														choicesKey: "rescue_scenario_urgent_mission_choices",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 this.missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Escort mission completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_5a_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();

		}
}

this.rescue_shipWillLaunchFromStation = function (rstation) {
		if (missionVariables.rescuestation_stage == 2 && rstation.hasRole("rescue_station")) {

				this.stagetimer = new Timer(this,this.insertArafura,150);
				this.notifytimer = new Timer(this,this.notifyDeadline,30);

				missionVariables.rescuestation_stage = 3;
		}

}

this.rescue_shipWillExitWitchspace = function() {
		if (missionVariables.rescuestation_stage < 100) {
				player.consoleMessage("You have abandoned the rescue mission");
				worldScripts["Rescue Stations"].failMission();
		}
}



/* Mission functions */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 10;
		// nothing special		
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 5; // easy to fail through no fault of own
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_system;
		delete missionVariables.rescuestation_shipname;
}

this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		} else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Downloading mission data",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_5a_mission_accepted",
													 choicesKey: "rescue_scenario_urgent_mission_launch",
													 model: "rrs-escort",
													 background: "rrsfl_blank_bg.png"},
													worldScripts["Rescue Scenario 5a"].missionOfferAccepted
												 );
		}
}

this.missionOfferAccepted = function (choice) {
		worldScripts["Rescue Stations"].acceptMission();
		worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_5a_description");
		player.ship.fuel = 7;
		player.ship.launch();
}

this.notifyDeadline = function() {
		var deadline = 5*Math.ceil(0.2*(this.stagetimer.nextTime - clock.absoluteSeconds));
		player.commsMessage("RRS: "+missionVariables.rescuestation_shipname+" wing ETA is "+deadline+" seconds");
		if (deadline > 30) {
				this.notifytimer = new Timer(this,this.notifyDeadline,30);				
		} else {
				this.notifytimer = new Timer(this,this.notifyDeadline,5);
		}
}

this.insertArafura = function() {
		var arafura = system.addShips("arafura-returning",1,[0,0,0],5E3);
		
		this.notifytimer.stop();
		this.stagetimer = new Timer(this,this.insertOpposition,5+(10*Math.random()));

		arafura[0].displayName = arafura[0].displayName + ": " + missionVariables.rescuestation_shipname+" Leader";
		arafura[0].commsMessage("[rescue_introuble]");
		arafura[0].escorts[0].displayName = arafura[0].escorts[0].displayName + ": " + missionVariables.rescuestation_shipname+" "+(2+Math.floor(Math.random()*5));

}

this.insertOpposition = function() {
		var opplevel = 2+worldScripts["Rescue Stations"].dangerScale(256);
		var opptype = Math.random();
		if (opptype < 0.6) {
				var opprole = "pirate";
				opplevel = opplevel*2;
		} else if (opptype < 0.9) {
				var opprole = "rrs-vicious-hunter";
		} else if (opptype < 0.98) {
				var opprole = "thargoid"; // just some basic ones
		} else {
				var opprole = "thargoid-mothership"; // allow tougher thargoids from OXPs
				opplevel = Math.floor(opplevel*0.75);
		}
		if (opplevel < 1) {
				opplevel = 1;
		}

		
		var pirates = system.addShips(opprole,opplevel,[0,0,0],5E3);
		if (!pirates) {
				log(this.name,"Couldn't add "+opprole);
		}

		var arafura = system.shipsWithRole("arafura-returning");

		for(var i=0;i<pirates.length;i++) {
				pirates[i].setScript("rescue_scenario_5_pirate.js");
				if (pirates[i].bounty == 0) {
						pirates[i].bounty = 1+Math.floor(Math.random()*5);
						pirates[i].switchAI("pirateAI.plist");
				}
				if (pirates[i].escorts) {
						for (var j=0;j<pirates[i].escorts.length;j++) {
								pirates[i].escorts[j].setScript("rescue_scenario_5_pirate.js");
						}
				}
				if (Math.random() < 0.5) {
						pirates[i].target = arafura[0];
				} else if (Math.random() < 0.5) {
						pirates[i].target = arafura[0].escorts[0];
				} else {
						pirates[i].target = player.ship;
				}
				if (!pirates[i].isThargoid) {
						pirates[i].setAI("interceptAI.plist");
				}
		}
		
		var reinforce = Math.floor(opplevel/3);
		if (reinforce < 1) {
				reinforce = 1;
		} else if (reinforce > 4) {
				reinforce = 4;
		}
		var rpos = player.ship.position.add(system.mainPlanet.position.direction().multiply(24E3));
				
		var reinforcements = system.addShips("rrs-defender",reinforce,rpos,1E3);
		for (var i=0;i<reinforcements.length;i++) {
				reinforcements[i].orientation = reinforcements[i].orientation.rotateY(Math.PI);
				reinforcements[i].target = pirates[Math.floor(Math.random()*pirates.length)];
				reinforcements[i].switchAI("policeInterceptAI.plist");
		}
		reinforcements[0].commsMessage("Reinforcements are coming! Keep them off the Arafura until we arrive, then we'll cover your escape.");
		
}
Scripts/rescue_scenario_5a_arafura.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 5a Arafura";

this.lastdamagecomplaint = 0;

this.stationPosition = function() {
		var rstation = system.shipsWithPrimaryRole("rescue_station");
		if (rstation.length > 0) {
				this.ship.savedCoordinates = rstation[0].position;
				this.ship.reactToAIMessage("RSTATION");
		}	else {
				this.ship.reactToAIMessage("NO_RSTATION");
		}
}

this.shipDied = function(whom,why) {
		this.ship.commsMessage("[rescue_argh]");
		var rstation = system.shipsWithPrimaryRole("rescue_station",player.ship,25600);
		if (rstation.length > 0) {
				rstation[0].commsMessage("[mission_rescuestation_shipname] Leader has been destroyed. Clear the opposition then return to base.");
//				rstation[0].reactToAIMessage("DOCKING_ABORTED");
		}
		worldScripts["Rescue Stations"].failMission();

		if (whom == player.ship) {
				missionVariables.rescuestation_reputation -= 20;
		}
}

this.shipWillDockWithStation = function(station) {
		station.commsMessage("[mission_rescuestation_shipname] Leader has docked safely. Contractors may dock when ready to be paid.");
		missionVariables.rescuestation_stage = 100;
}

this.shipTakingDamage = function(amount,whom,type) {
		if (this.ship.energy > 0) {
				if (this.lastdamagecomplaint+10 < clock.seconds) {
						this.lastdamagecomplaint = clock.seconds;
						if (this.ship.energy > this.ship.maxEnergy/4) {
								this.ship.commsMessage("[rescue_underfire]");
						} else {
								this.ship.commsMessage("[rescue_underheavyfire]");
						}

						var ships = system.shipsWithPrimaryRole("rrs-defender");
						for (var i=0;i<ships.length;i++) {
								if (!ships[i].target) {
										if (ships[i].AI != "policeInterceptAI.plist") {
												ships[i].target = whom;
												ships[i].setAI("policeInterceptAI.plist");
										} else {
												ships[i].reactToAIMessage("GROUP_ATTACK_TARGET");
												ships[i].target = whom;
										}
								}
						}
				}				
		}
}

this.getDC = function() {
		var dc = this.ship.target.position.add(this.ship.target.vectorForward.multiply(3E3));
		this.ship.savedCoordinates = dc;
		this.ship.reactToAIMessage("CORRIDOR_POSITION");
}

this.getDB = function() {
		var db = this.ship.target.position;
		this.ship.savedCoordinates = db;
}


/* Autopilot functions block */

this.autopilotModeReady = function() {
		this.autopilotwilling = 1;
}

this.autopilotModeOffline = function() {
		this.autopilotwilling = 0;
}

this.autopilotContinue = function() {
		worldScripts["Rescue Autopilot"].autopilotStep(this.ship);
}
Scripts/rescue_scenario_6.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 6"; 
this.description = "This script adds scenario 6 rescue mission."; 

//added long range map to the mission screens -spara-
//added background images to mission screens without model -spara-
//fixed description expand bug -spara-

this.scenarioID = "6";

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerScenario(this.scenarioID);
}

this.missionAvailableCount = function(iteration) {
		// ~75% 1, ~15% 2, ~5% 3, ~5% 4
		var x = Math.sqrt(Math.random()/Math.random());
		if (x > 4) {
				return 4;
		} else if (x < 1) {
				return 1;
		} else {
				return Math.floor(x);
		}
}

this.targetSystems = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				if (!((other.systemID !== system.info.systemID) && 
						(!other.sun_gone_nova) &&
						(worldScripts["Rescue Stations"].systemHasRescueStation(other.systemID)) &&
						(system.info.distanceToSystem(other) > 7) &&
							(system.info.distanceToSystem(other) <= 25))) {
						return false;
				} else {
						var route = system.info.routeToSystem(other);
						return (route && route.distance <= 25);
				}
		});
}


this.missionAvailable = function() {
		if (Math.random() > 0.75) {
				return false; // often available
		}
		if (missionVariables.rescuestation_reputation < 0) {
				return false; // bad reputation
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (this.targetSystems().length < 1) {
				return false; // no suitable systems
		}
		return true;
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_system = system.ID;
		
		var nearby = this.targetSystems();
		var destination = nearby[Math.floor(nearby.length*Math.random())];

		missionVariables.rescuestation_destsystem = destination.systemID;
		missionVariables.rescuestation_destsystem_name = destination.name;

		var direction = worldScripts["Rescue Stations"].getDirection(system.info,destination);

		missionVariables.rescuestation_destsystem_desc = destination.name+" ("+expandDescription("[rescue_govname_"+destination.government+"]")+", "+Math.round(system.info.distanceToSystem(destination))+" LY "+direction+")";

		var timer = (2+Math.random())*(system.info.routeToSystem(destination).time);
		var deadline = (3600*timer)+clock.seconds;

		missionVariables.rescuestation_deadline = deadline;
		missionVariables.rescuestation_deadline_text = clock.clockStringForTime(deadline);

		var reward = Math.floor(system.info.routeToSystem(destination).distance * 20);
		missionVariables.rescuestation_reward = reward;

		if (Math.random() < 0.25) {
				missionVariables.rescuestation_danger = 3 + worldScripts["Rescue Stations"].dangerScale(128); 
		} else {
				missionVariables.rescuestation_danger = 0;
		}

		

}

this.rescue_shipDockedWithStation = function (rstation) {
		
		if (rstation.hasRole("rescue_station") && system.ID == missionVariables.rescuestation_destsystem && missionVariables.rescuestation_stage == 2) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 1000;
				} else {
						missionVariables.rescuestation_stage = 1001;
				}
		}

}

this.rescue_missionScreenOpportunity = function() {
		if (worldScripts["Rescue Stations"].restoreDestination) {
			player.ship.targetSystem = worldScripts["Rescue Stations"].restoreDestination;
			delete worldScripts["Rescue Stations"].restoreDestination;
		}
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Package transportation needed",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_6_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices_map",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Delivery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_6_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();
		} else if (missionVariables.rescuestation_stage == 1001) {
				var lateness = clock.seconds - missionVariables.rescuestation_deadline;
				if (lateness > 864000) {
						lateness = 864000; // more than 10 days late and it doesn't matter
				}
				missionVariables.rescuestation_reputation += 5; // partial mitigation
				missionVariables.rescuestation_reputation -= Math.floor(lateness/86400); // each extra day late makes it worse
				
				mission.runScreen({title: "Delivery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_6_mission_toolate",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].failMission();

		}
}


this.rescue_shipWillExitWitchspace = function() {
		if (missionVariables.rescuestation_danger > 0) {
				if (system.ID == missionVariables.rescuestation_destsystem) {
						var appear = missionVariables.rescuestation_danger; // use all the rest
				} else {
						var appear = Math.floor(Math.random()*missionVariables.rescuestation_danger);
				}
				if (appear > 1) { 
						var assassins = system.addShips("rrs-vicious-hunter",appear,player.ship.position.add(Vector3D.random(14E3),1E3));
						for (var i=0;i<assassins.length;i++) {
								var assassin = assassins[i];
								assassin.target = player.ship;
								assassin.setAI("interceptAI.plist");
						}
						missionVariables.rescuestation_danger -= appear;					
				}
		}
}

this.rescue_shipExitedWitchspace = function() {
		var assassins = system.shipsWithPrimaryRole("rrs-vicious-hunter",player.ship,25600);
		if (assassins.length > 0) {
			assassins[0].commsMessage("[rescue_scenario_6_conspirator_target]");
		}
		
}


/* Mission setup */

this.missionSuccess = function() {
		missionVariables.rescuestation_reputation += 5; // only really useful for complete beginners and restoring a damaged reputation, though it does also stop rep decay if you were going that way anyway
		// nothing special		
}

this.failMission = function () {
		missionVariables.rescuestation_reputation -= 5; // hard to get wrong
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_system;
		delete missionVariables.rescuestation_danger;
		delete missionVariables.rescuestation_destsystem;
		delete missionVariables.rescuestation_destsystem_name;
		delete missionVariables.rescuestation_destsystem_desc;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_deadline_text;
}


this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		}
		else if (choice === "MAP") {
			worldScripts["Rescue Stations"].restoreDestination = player.ship.targetSystem;
			player.ship.targetSystem = missionVariables.rescuestation_destsystem;
				mission.runScreen ({title: "Package transportation needed",
														screenID: "rrs_mission_map",
														backgroundSpecial: "LONG_RANGE_CHART_QUICKEST"
														},
														worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_missionScreenOpportunity
													);
		}
		 else {
				missionVariables.rescuestation_stage = 2;
				mission.runScreen({title: "Transferring package",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_6_mission_accepted",
													 model: "rescue_blackbox",
													 background: "rrsfl_blank_bg.png"},
													function (choice) {
															worldScripts["Rescue Stations"].acceptMission();
															mission.markSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
															worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_6_description");
													}
												 );
		}
}

/* Mission functions */

Scripts/rescue_scenario_6a.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name        = "Rescue Scenario 6a"; 
this.description = "This script adds scenario 6 variant A rescue mission."; 

//added long range map to the mission screens -spara-
//made plague mine position fixed -spara-
//added background images to mission screens without model -spara-
//fixed description expand bug -spara-

this.scenarioID = "6a";

this.addedpirates = 0;
this.piratetimer = undefined;

this.startUp = function() {
// make sure Rescue Stations is loaded first
		if (worldScripts["Rescue Stations"].startUp) {
				worldScripts["Rescue Stations"].startUp();
		}
		worldScripts["Rescue Stations"].registerVariant("6",this.scenarioID);
}

this.targetSystems2 = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				if (!((other.systemID !== system.info.systemID) && 
						(!other.sun_gone_nova) &&
						(other.description.indexOf("disease") != -1) &&
						(system.info.distanceToSystem(other) > 7) &&
							(system.info.distanceToSystem(other) < 30))) {
						return false;
				} else {
						var route = system.info.routeToSystem(other);
						return (route && route.distance <= 30);
				}
		});
}

this.targetSystems1 = function() {
		return SystemInfo.filteredSystems(this, function (other) {
				if (!((other.description.indexOf("disease") == -1) &&
							(!other.sun_gone_nova) &&
							(other.techlevel >= 11) &&
							(system.info.distanceToSystem(other) <= 15) && 
							(other.economy <= 1))) { // Rich/Avg industrials
								return false;
				} else {
						var route = system.info.routeToSystem(other);
						return (route && route.distance <= 15);
				}
		});
}


this.missionAvailable = function() {
		if (Math.random() > 0.3) {
				return false; // sometimes replace
		}
		if (missionVariables.rescuestation_reputation < 40) {
				return false; // not enough reputation
		}
		if (player.bounty > 50) {
				return false; // no fugitives
		}
		if (this.targetSystems1().length < 1) {
				return false; // no suitable systems
		}
		if (this.targetSystems2().length < 1) {
				return false; // no suitable systems
		}
		return true;
}

this.initMissionVariables = function() {
		missionVariables.rescuestation_system = system.ID;
		
		var nearby = this.targetSystems1();
		if (nearby.length == 0) {
				log(this.name,"No target systems found");
		}
		var destination1 = nearby[Math.floor(nearby.length*Math.random())];

		missionVariables.rescuestation_destsystem = destination1.systemID;
		missionVariables.rescuestation_destsystem_name = destination1.name;

		var direction = worldScripts["Rescue Stations"].getDirection(system.info,destination1);

		missionVariables.rescuestation_destsystem_desc = destination1.name+" ("+expandDescription("[rescue_govname_"+destination1.government+"]")+", "+Math.round(system.info.distanceToSystem(destination1))+" LY "+direction+")";

		var timer = (1.1+Math.random())*(system.info.routeToSystem(destination1).time);

		nearby = this.targetSystems2();
		var destination2 = nearby[Math.floor(nearby.length*Math.random())];
		missionVariables.rescuestation_destsystem2 = destination2.systemID;
		missionVariables.rescuestation_destsystem2_name = destination2.name;

		direction = worldScripts["Rescue Stations"].getDirection(system.info,destination2);

		missionVariables.rescuestation_destsystem2_desc = destination2.name+" ("+expandDescription("[rescue_govname_"+destination2.government+"]")+", "+Math.round(system.info.distanceToSystem(destination2))+" LY "+direction+")";

		timer += (1.1+Math.random())*(destination1.routeToSystem(destination2).time);
		var deadline = (3600*timer)+clock.seconds;

		missionVariables.rescuestation_deadline = deadline;
		missionVariables.rescuestation_deadline_text = clock.clockStringForTime(deadline);

		var reward = Math.floor(system.info.routeToSystem(destination2).distance * 100);
		missionVariables.rescuestation_reward = reward;

		missionVariables.rescuestation_danger = 2 + worldScripts["Rescue Stations"].dangerScale(192); 

		missionVariables.rescuestation_disease = expandDescription("[rescue_random_disease]");

}

this.rescue_shipDockedWithStation = function (rstation) {
		
		if (rstation.isMainStation && system.ID == missionVariables.rescuestation_destsystem && missionVariables.rescuestation_stage == 2) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 90;
				} else {
						missionVariables.rescuestation_stage = 1002;
				}
		} else if (rstation.hasRole("rrs-plague-mine") && system.ID == missionVariables.rescuestation_destsystem2 && missionVariables.rescuestation_stage >= 100) {
				if (clock.seconds < missionVariables.rescuestation_deadline) {
						missionVariables.rescuestation_stage = 1000;
				} else {
						missionVariables.rescuestation_stage = 1001;
				}

		}

}

this.rescue_populatingSystem = function() {
		if (system.ID == missionVariables.rescuestation_destsystem2) {
			var i = 1;
			do {
				var mineloc = Vector3D(system.scrambledPseudoRandomNumber(i), system.scrambledPseudoRandomNumber(i + 1), system.scrambledPseudoRandomNumber(i + 2)).multiply(400E3);
				i++;
			} while (mineloc.magnitude() < 100E3);
				system.addShips("rrs-plague-mine",1,mineloc,1);
				system.addShips("asteroid", 30+Math.floor(Math.random()*30), mineloc, 40E3);
				system.addShips("miner",3,mineloc,20E3);
				var pirateCount = 1+Math.floor(Math.random()*missionVariables.rescuestation_danger);
				system.addGroup("pirate", pirateCount, [0,0,0], 15E3);

		}
}

this.rescue_shipExitedWitchspace = function() {
		if (this.piratetimer) {
				this.piratetimer.stop();
		}
		if (missionVariables.rescuestation_stage >= 100) {
				this.addedpirates = 0;
				this.additionalPirates();
		}
		if (system.ID == missionVariables.rescuestation_destsystem2) {
				if (!worldScripts["Rescue Ambience"].plagueActive()) {
						// there is an unseasonable plague here
						worldScripts["Rescue Ambience"].plagueSystem();
				}
		}
}

this.rescue_missionScreenOpportunity = function() {
		if (worldScripts["Rescue Stations"].restoreDestination) {
			player.ship.targetSystem = worldScripts["Rescue Stations"].restoreDestination;
			delete worldScripts["Rescue Stations"].restoreDestination;
		}
		if (missionVariables.rescuestation_stage == 1) {
				mission.runScreen ({title: "Medical supplies delivery",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_6a_mission_available",
														choicesKey: "rescue_scenario_nonurgent_mission_choices_map",
														model: "rescue_station",
														background: "rrsfl_blank_bg.png"},
													 worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].missionOfferDecision
													);
		} else if (missionVariables.rescuestation_stage == 90) {
				mission.runScreen ({title: "Medical supplies delivery",
														screenID: "rrs_mission",
														messageKey: "rescue_scenario_6a_mission_progress",
														model: "1t-cargopod",
														background: "rrsfl_blank_bg.png"});
				missionVariables.rescuestation_stage = 100;
				mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
				mission.markSystem({system: missionVariables.rescuestation_destsystem2, name: "RRS"});

				player.ship.useSpecialCargo("RRS Medical Supplies");

		} else if (missionVariables.rescuestation_stage == 1000) {
				var reward = missionVariables.rescuestation_reward;
				player.credits += reward;

				mission.runScreen({title: "Delivery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_6a_mission_complete",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].missionSuccess();
		} else if (missionVariables.rescuestation_stage == 1001) {
				var lateness = clock.seconds - missionVariables.rescuestation_deadline;
				if (lateness > 864000) {
						lateness = 864000; // more than 10 days late and it doesn't matter
				}
				missionVariables.rescuestation_reputation += 5; // partial mitigation
				missionVariables.rescuestation_reputation -= Math.floor(lateness/86400); // each extra day late makes it worse
				
				mission.runScreen({title: "Delivery completed",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_6a_mission_toolate",
													 background: "rrsfl_bg.png"});

				worldScripts["Rescue Stations"].failMission();
		} else if (missionVariables.rescuestation_stage == 1002) {
				missionVariables.rescuestation_reputation -= 5; // serious error
				mission.runScreen({title: "We found someone else",
													screenID: "rrs_mission",
													 messageKey: "rescue_scenario_6a_mission_reallylate",
													 background: "rrsfl_bg.png"});
				worldScripts["Rescue Stations"].failMission();
		}
}



/* Mission setup */

this.missionSuccess = function() {
		mission.unmarkSystem({system: missionVariables.rescuestation_destsystem2, name: "RRS"});
		missionVariables.rescuestation_reputation += 15; 
		// nothing special		
		player.ship.removeAllCargo(); // remove the special cargo
}

this.failMission = function () {
		if (missionVariables.rescuestation_stage >= 100) {
				player.ship.removeAllCargo();  // remove the special cargo
		}
		mission.unmarkSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
		mission.unmarkSystem({system: missionVariables.rescuestation_destsystem2, name: "RRS"});
		missionVariables.rescuestation_reputation -= 10; 

		var chance = 0.9;
		if (missionVariables.rescuestation_stage == 1001) {
				chance = 0.5; // better late than never?
		}

		worldScripts["Rescue News"].sendNews("rescue_scenario_6a_news",1,chance); // bad news
}

this.cleanupMission = function() {
		delete missionVariables.rescuestation_reward;
		delete missionVariables.rescuestation_system;
		delete missionVariables.rescuestation_danger;
		delete missionVariables.rescuestation_destsystem;
		delete missionVariables.rescuestation_destsystem_name;
		delete missionVariables.rescuestation_destsystem_desc;
		delete missionVariables.rescuestation_destsystem2;
		delete missionVariables.rescuestation_destsystem2_name;
		delete missionVariables.rescuestation_destsystem2_desc;
		delete missionVariables.rescuestation_deadline;
		delete missionVariables.rescuestation_deadline_text;
		if (this.piratetimer) {
				this.piratetimer.stop();
		}
}


this.missionOfferDecision = function (choice) {
		if (choice == "NO") {
				worldScripts["Rescue Stations"].refuseCurrentMission();
				worldScripts["Rescue Stations"].cleanupMission();
				missionVariables.rescuestation_stage = 0;
		}
		else if (choice === "MAP" || choice === "SWAP") {
			var options = {
				"1_SWAP" : "Swap destination",
				"2_RETURN" : "Return"
			};
			if (choice === "MAP") {
				worldScripts["Rescue Stations"].restoreDestination = player.ship.targetSystem;
				player.ship.targetSystem = missionVariables.rescuestation_destsystem;
			}
			else {
				if (player.ship.targetSystem === missionVariables.rescuestation_destsystem)
					player.ship.targetSystem = missionVariables.rescuestation_destsystem2;
				else
					player.ship.targetSystem = missionVariables.rescuestation_destsystem;
			}
			mission.runScreen ({
					title: "Medical supplies delivery",
					screenID: "rrs_mission_map",
					backgroundSpecial: "LONG_RANGE_CHART_QUICKEST",
					choices: options
				},
				function (choice) {
					if (choice === "1_SWAP") {
						worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].missionOfferDecision("SWAP");
						return;
					}
					else {
						worldScripts["Rescue Scenario "+missionVariables.rescuestation_scenario].rescue_missionScreenOpportunity();
						return;
					}
				}
			);
		}
		else {
			missionVariables.rescuestation_stage = 2;
			mission.runScreen({
					title: "Transferring package",
					screenID: "rrs_mission",
					messageKey: "rescue_scenario_6a_mission_accepted",
					model: "rescue_blackbox"
				},
				function (choice) {
						worldScripts["Rescue Stations"].acceptMission();
						mission.markSystem({system: missionVariables.rescuestation_destsystem, name: "RRS"});
						worldScripts["Rescue Stations"].setMissionDetails("rescue_scenario_6a_description");
				}
			);
		}
}

		
/* Mission functions */



this.additionalPirates = function() {
		if (!player.ship.docked) {
				this.addedpirates++;
				var pirateCount = 1+Math.floor(Math.random()*missionVariables.rescuestation_danger);
				var addplace = player.ship.position.add(player.ship.vectorForward.multiply(50E3));
				system.addGroup("pirate", pirateCount, addplace, 10E3);
		}
		
		if (this.addedpirates <= missionVariables.rescuestation_danger) {
				if (system.ID == missionVariables.rescuestation_destsystem2) {
						var delay = 10*(1+system.info.government)+Math.floor(Math.random()*20);
				} else {
						var delay = (20*(4+system.info.government))+Math.floor(Math.random()*20);
				}
				if (this.piratetimer) {
						this.piratetimer.stop();
				}
				this.piratetimer = new Timer(this,this.additionalPirates,delay);
		}

}

Scripts/rescue_scenario_6a_miningbase.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "Rescue Scenario 6a Mining Base";

//support for escort formations oxp -spara-

this.shipSpawned = function () {
	if (worldScripts["Escort Formations Randomiser"]) {
		worldScripts["Escort Formations Randomiser"].$setupDefensiveEscorts(this.ship);
	};
}

this.shipDied = function() {
		player.consoleMessage("Mining base destroyed. Mission failed.");
		worldScripts["Rescue Stations"].failMission();
}
Scripts/rrs_eq_cargo.js
"use strict";

this.name           =    "rrs_eq_cargo_holder";
this.author         =    "spara";
this.copyright      =    "2015 Mika Spåra";
this.licence        =    "CC BY-NC-SA 3.0"; 
this.description    =    "RRS cargo holder condition script for scripted pods";

this.allowAwardEquipment = function(eqKey, ship, context) {	
	//add only via scripting
	if (context === "scripted")
		return true;
	return false;
}
Scripts/rrs_eq_cond.js
"use strict";

this.name           =    "rrs_eq_cond";
this.author         =    "spara";
this.copyright      =    "2015 Mika Spåra";
this.licence        =    "CC BY-NC-SA 3.0"; 
this.description    =    "RRS equipment condition script";

this.allowAwardEquipment = function(eqKey, ship, context) {
	
	//add EQ_RESQUE_MISSILE only via scripting
	if (eqKey === "EQ_RESCUE_MISSILE") {
		if (context === "scripted") return true;
		else return false;
	}
	//rrs equipment available only from waystation
	if (!player.ship.dockedStation.hasRole("rescue_station"))
		return false;
		
	switch(eqKey) {
		case "EQ_RRS_SOLAR_MINE":
			if (missionVariables.rescuestation_solarlabavailable !== 1)
				return false;
			break;
		case "EQ_RRS_FUEL":
			if (missionVariables.rescuestation_reputation < 20)
				return false;
			break;
		case "EQ_RRS_SCOOPS":
		case "EQ_RRS_DOCK_COMP":
		case "EQ_RRS_HEAT_SHIELD":
		case "EQ_RRS_ASC":
		case "EQ_RRS_ANA":
		case "EQ_RRS_FLIGHTFORM_DISCOUNT":
		case "EQ_RRS_ESCORT_TARGETING_SYSTEM_DISCOUNT":
		case "EQ_RRS_SCANNER_SHOW_MISSILE_TARGET_DISCOUNT":
			if (missionVariables.rescuestation_reputation < 40 || missionVariables.rescuestation_reputation > 318)
				return false;
			break;
		case "EQ_RRS_SERVICE":
			if (missionVariables.rescuestation_reputation < 160)
				return false;
			break;
		case "EQ_RRS_FULLEQUIP":
			if (missionVariables.rescuestation_reputation < 320)
				return false;
			break;
	}
	return true;
}
Scripts/rrs_escort.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "RRS Escort";
this.description = "Scripts for the Escorts";

//naming retouching -spara-

this.lastdamagecomplaint = 0;

this.shipSpawned = function() {
	if (worldScripts.randomshipnames && (!this.ship.owner || (this.ship.owner && !this.ship.owner.hasRole("rrs-arafura") && !this.ship.owner.hasRole("arafura-mission"))))
		this.ship.displayName = this.ship.displayName + ": " + worldScripts.randomshipnames.$randomHunterName(this.ship);
}

this.shipDied = function(whom,why) {
		this.ship.commsMessage("[rescue_argh]");
		if (whom == player.ship) {
				missionVariables.rescuestation_reputation -= 10;
		}

/*		if (whom) {
				player.consoleMessage(this.ship.displayName+" killed by "+whom.displayName+" using "+why);
		} else {
				player.consoleMessage(this.ship.displayName+" killed by anonymous using "+why);
		}*/


}

this.shipKilledOther = function(whom) {
		this.ship.commsMessage("[rescue_kill]");
}

this.shipAttackedWithMissile = function(missile,whom) {
		if (!this.ship.equipmentStatus("EQ_ECM") != "EQUIPMENT_OK") {
				this.ship.commsMessage("[rescue_incmissile]");
		}
}

this.shipTakingDamage = function(amount,whom,type) {
		if (type == "scrape damage" && (whom.hasRole("arafura-mission") || whom.hasRole("rrs-escort") || whom.hasRole("rescue_target"))) {
				this.ship.energy += amount; // cancel damage from collision with leader
				return;
		}
		if (!this.ship.piloted) {
				return;
		}
		if (this.ship.energy > 0) {
				if (this.lastdamagecomplaint+15 < clock.seconds) {
						this.lastdamagecomplaint = clock.seconds;
						if (this.ship.energy > this.ship.maxEnergy/4) {
								this.ship.commsMessage("[rescue_underfire]");
						} else {
								this.ship.commsMessage("[rescue_underheavyfire]");
						}
				}				
		}
}
Scripts/rrs_escorttargeting.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "RRS Escort Targeting Equipment";

this.filter = function(entity) {
		return entity.isShip && entity.target && entity.hasHostileTarget;
}

this.activated = function() {
		if (!player.ship.target) {
				player.consoleMessage("No target selected");
				return;
		}
		
		var possibles = system.filteredEntities(this,this.filter,player.ship,25600);
		
		for (var i=0;i<possibles.length;i++) {
				if (possibles[i].target == player.ship.target && possibles[i] != player.ship.target) {
						player.ship.target = possibles[i];
						player.consoleMessage("Target locked");
						return;
				}
		}

		player.consoleMessage("No hostile target found");
}
Scripts/rrs_flightpilot.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "RRS Formation Flight Autopilot";
this.description = "An autopilot for those boring escort bits";

this.equipmentactive = 0;
this.checkstatus = undefined;
this.autotarget = undefined;
this.music = "uranus.ogg";

this.activated = function() {
		if (this.equipmentactive == 0) {
				if (system.shipsWithRole("rrs-autopilot-screen").length > 0) {
						player.consoleMessage("Please wait for subsystem reboot to complete");
						return;
				}
				this.autopilotOn();
		} else {
				this.autopilotOff();
		}
}

this.autopilotAvailable = function() {
		if (player.ship.equipmentStatus("EQ_DOCK_COMP") != "EQUIPMENT_OK") {
				return "Severe damage to autopilot computers";
		} else if (player.alertCondition == 0) {
				return "Cannot be used while docked";
		} else if (player.alertCondition == 3) {
				return "Cannot be used while at red alert";
		} else if (player.alertEnergy) {
				return "Energy banks are not full";
		} else if (!player.ship.target) {
				return "Select mothership to follow as target";
		} else if (!player.ship.target.hasRole("rrs-flightcomp-supported")) {
				return "Selected target does not support this equipment";
		} else if (!player.ship.target.script.autopilotwilling) {
				return "Selected target is not currently transmitting";
		} else if (player.ship.target.savedCoordinates.distanceTo(player.ship.target.position) < 25E3) {
				return "Selected target already in destination vicinity";
		} else {

				var range = player.ship.position.distanceTo(player.ship.target.position);
				var speedmatch = player.ship.velocity.magnitude()/player.ship.target.velocity.magnitude();
				var headmatch = player.ship.velocity.direction().dot(player.ship.target.velocity.direction());

				if (range > 25E2) {
						return "Approach to within 2500m of selected target";
				} else if (range < 5E2) {
						return "Withdraw to at least 500m away from selected target";
				} else if (speedmatch < 0.9) {
						return "Accelerate to match target speed";
				} else if (speedmatch > 1.1) {
						return "Decelerate to match target speed";
				} else if (headmatch < 0.99) {
						return "Turn to match target heading";
				} else {
						return "READY";
				}
		}
}

this.autopilotOn = function() {
		var available = this.autopilotAvailable();
		if (available == "READY") {
				this.autopilotActive();
		} else {
				player.consoleMessage(available,5);
				player.consoleMessage("Please fix error and then reactivate",5);
		}
}

this.autopilotActive = function() {
		this.equipmentactive = 1;
		this.autotarget = player.ship.target;
		this.checkstatus = new Timer(this,this.autopilotCheckState,3);
		player.ship.target.reactToAIMessage("PLAYER_ESCORT_AUTOPILOT_ON");
		player.consoleMessage("Autopilot initialising",5);
		var screen = system.addShips("rrs-autopilot-screen",1,player.ship.position.add(player.ship.vectorUp.multiply(player.ship.collisionRadius*4)));
		screen[0].orientation = player.ship.orientation;
		screen[0].velocity = player.ship.velocity;
		Sound.playMusic(this.music);

}

this.autopilotCheckState = function() {
		if (this.equipmentactive != 1) {
				return;
		}
		var available = this.autopilotAvailable();
		if (available == "READY") {
				player.ship.hudHidden = true;
				// schedule another check
				var screen = system.shipsWithRole("rrs-autopilot-screen");
				screen[0].position = player.ship.position.add(player.ship.vectorUp.multiply(player.ship.collisionRadius*4));
				this.checkstatus = new Timer(this,this.autopilotCheckState,1);
		} else {
				player.consoleMessage("Exiting autopilot mode!");
				// quit autopilot
				this.autopilotOff();
		}
}

this.autopilotOff = function() {
		player.ship.hudHidden = false;
		Sound.stopMusic(this.music);
		if (this.equipmentactive == 0) {
				return;
		}
		this.equipmentactive = 0;
		var screen = system.shipsWithRole("rrs-autopilot-screen");
		screen[0].remove(true);
//		worldScripts["Rescue Autopilot"].autopilotShutdown();
		if (this.checkstatus) {
				this.checkstatus.stop();
		}
		if (this.autotarget.isValid && this.autotarget.isShip) {
				this.autotarget.reactToAIMessage("PLAYER_ESCORT_AUTOPILOT_OFF");
		}
		this.autotarget = undefined;
		player.consoleMessage("Autopilot disengaged");
}

Scripts/rrs_hq_script.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "RRS Headquarters Script";

this.dockposition = undefined;

this.initialiseStation = function() {
		var busyness = Math.random()/2;
		var subents = this.ship.subEntities;
		var bays = new Array();
		var ffs = new Array();
		var positions = new Array();
		for (var i=0;i<subents.length;i++) {
				if (subents[i].hasRole("rrs_hq_bay")) {
						bays.push(subents[i]);
						if (!subents[i].hasRole("rrs_hq_bay_dock")) {
								positions.push(subents[i].position);
						} else {
								var activedockpos = subents[i].position;
						}
				} else if (subents[i].hasRole("rrs_hq_ff")) {
						ffs.push(subents[i]);
				} else if (!subents[i].hasRole("rrs_hq_component")) {
						if (Math.random() < busyness) {
								subents[i].remove(true)
						}
				}
		}
		
		positions.sort(function(a,b) { return Math.random()-0.5; });
		for (var i=0;i<bays.length;i++) {
				if (bays[i].hasRole("rrs_hq_bay_dock")) {
						for (var j=0;j<ffs.length;j++) {
								if (ffs[j].position.distanceTo(bays[i].position) < 50) {
										ffs[j].remove(true);
								}
						}
						this.dockposition = bays[i].position;
				} else {
						bays[i].position = positions.shift();
				}
		}

		system.addShips("rrs-hq-buoy",1,this.ship.position.add(activedockpos).add(this.ship.vectorForward.multiply(12E3)),1);

}
Scripts/rrs_market.js
"use strict";

this.name = "rescue-stations-market";
this.author = "spara";
this.copyright = "2015 spara";
this.license     = "CC BY-NC-SA 4.0";

this.$originalDefsWayStation = {
      "food" : [0, 0, 28,  -2, 0,  0,  3,  0,  0],
      "textiles" : [0, 0, 30,  -1, 0,  0,  3,  0,  0],
      "radioactives" : [0, 0, 50,  -3, -1, 6,  7,  3,  0],
      "slaves" : [0, 0, 25,  0,  0,  0,  0,  0,  0],
      "liquor_wines" : [0, 0, 75,  -5, 0,  0,  15, 0,  0],
      "narcotics" : [0, 0, 50,  0,  0,  0,  0,  0,  0],
      "computers" : [0, 0, 160, 9,  9,  2,  7,  7,  0],
      "machinery" : [0, 0, 120, 4,  4,  4,  7,  7,  0],
      "alloys" : [0, 0, 80,  1,  1,  10, 15, 15, 0]
};

this.$originalDefsHQ = {
      "food" : [0, 0, 22,  -2, 0,  0,  3,  0,  0],
      "radioactives" : [0, 0, 60,  -3, 0,  0,  7,  0,  0],
      "computers" : [0, 0, 160, 9,  9,  2,  7,  7,  0],
      "machinery" : [0, 0, 120, 4,  4,  4,  7,  7,  0],
      "alloys" : [0, 0, 80,  1,  1,  10, 15, 15, 0],
      "furs" : [0, 0, 24,  -1, -1, 85, 3,  3,  0]
};

this.updateLocalCommodityDefinition = function(goodDefinition, station) {
	var commodity = goodDefinition.key;
	if (station.dataKey === "rescue_station")
		var oldDefs = this.$originalDefsWayStation[commodity];
	else var oldDefs = this.$originalDefsHQ[commodity];
	
	//these are smallish markets
	goodDefinition.capacity = 31;
	
	//old style definition found for the good. calculate it the old way
	if (oldDefs) {
		var market_base_price = oldDefs[2];
		var market_eco_adjust_price = oldDefs[3];
		var market_eco_adjust_quantity = oldDefs[4];
		var market_base_quantity = oldDefs[5];
		var market_mask_price = oldDefs[6];
		var market_mask_quantity = oldDefs[7];
		var market_rnd = Math.floor(Math.random() * 256);

		var economy = system.economy;
		
		var price = (market_base_price + (market_rnd & market_mask_price) + (economy * market_eco_adjust_price)) & 255;
		price *= 0.4;
		
		var quantity = (market_base_quantity + (market_rnd & market_mask_quantity) - (economy * market_eco_adjust_quantity)) & 255;
		if (quantity > 127) quantity = 0;
		
		quantity &= 63;
		
		goodDefinition.quantity = quantity;
		goodDefinition.price = price * 10;
	}
	//no definition found. good is not tradeable
	else {
		goodDefinition.price = 0.0;
		goodDefinition.quantity = 0;
		goodDefinition.capacity = 0;
	}
	return goodDefinition;
};
Scripts/rrs_player_hunter.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Player Hunters";
this.description = "Player Hunters";

this.findPlayer = function() {
		if (this.ship.position.distanceTo(player.ship.position) < 20E3) {

				this.ship.reactToAIMessage("PLAYER_FOUND");
		}
//		player.consoleMessage(this.ship.name+": "+this.ship.position.distanceTo(player.ship.position));

		if (player.ship.speed > player.ship.maxSpeed*10 && Math.random() < 0.15 && player.ship.position.distanceTo(this.ship.position) > 30E3) { // torus drive
				this.ship.position = player.ship.position.add(player.ship.vectorForward.multiply(60E3)); // teleporting is cheating, but then these ships don't have torus drives of their own
		}

		var lead = system.mainStation.position.subtract(player.ship.position).direction().multiply(10E3); // 10km ahead of player towards station

		this.ship.savedCoordinates = player.ship.position.add(lead);
		
}

Scripts/rrs_solar_lab.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "RRS Solar Lab";
this.description = "Functions for the RRS portable Solar Laboratory";

this.lasttemp = -1;
this.reacted = 0;
this.started = 0;

this.replaceIfNeeded = function() {
		if (this.ship.primaryRole == "EQ_RRS_SOLAR_MINE") {
				var p = this.ship.position;
				this.ship.remove(true);
				system.addShips("rrs_portable_solar_lab",1,p,1);
		} else {
				worldScripts["Rescue Stations"].solarLabDeployed();
		}
}

this.checkProgress = function() {
		var temp = this.ship.temperature;
		if (this.lasttemp == -1) {
				this.lasttemp = temp;
				return; // first check
		}

		this.reacted = 1;
		this.reactionComplete();

//		log(this.name,"Temperature: "+temp);
		if (temp <= this.lasttemp && temp < 0.75) {
				this.ship.commsMessage("ERR#9: Too far from sun. Please collect and redeploy");
				this.lasttemp = temp;
				return; // first check
		}
		if (temp > 0.9) {
				this.ship.commsMessage("ERR#5: Thermal overload. Please collect immediately.");
		} else if (temp > 0.75) {
				if (!this.reacted) {
						this.reacted = 1;
						this.reactionComplete();
				}
		} else {
				if (!this.started) {
						this.ship.commsMessage("Processing in progress.");
						this.started = 1;
				}
		}
		this.lasttemp = temp;
}

this.reactionComplete = function() {
// check for mission success, use event handler
		worldScripts["Rescue Stations"].solarLabReactionComplete();
		this.ship.commsMessage("Reaction complete. Collect lab now.");
//		log(this.name,"Reaction completed");
}

this.shipDied = function() {
		worldScripts["Rescue Stations"].solarLabDestroyed();
}

this.shipWasScooped = function(scooper) {
		scooper.awardEquipment("EQ_RRS_SOLAR_MINE");
		worldScripts["Rescue Stations"].solarLabCollected(scooper);
}
Scripts/rrs_witchspace_anomaly.js
"use strict";

this.author      = "cim"; 
this.copyright   = "2011-2015 cim."; 
this.licence = "CC-BY-SA 3.0";
this.name = "RRS witchspace anomaly script";

//added anomaly with effectdata -spara-

this.effectSpawned = function() {
	this.$diceTimer = new Timer(this, this.$handleActions, 5);
}

this.$handleActions = function() {
	var roll = Math.random();
	if (roll < 0.2) this.$moveAnomaly();
	else if (roll > 0.8) this.$doAnomaly();
	else
		this.$diceTimer = new Timer(this, this.$handleActions, Math.ceil(roll * 6));
}

this.$moveAnomaly = function() {
	this.$moveTime = clock.seconds + 3 + Math.floor(Math.random() * 4);//move for 3-6 seconds
	this.$moveDirection = Vector3D.randomDirection().multiply(10);
	this.$moveFCB = addFrameCallback(this.$doMove.bind(this));	
}

this.$doMove = function(delta) {
	if (this.$moveTime > clock.seconds) {
		this.visualEffect.position = this.visualEffect.position.add(this.$moveDirection);
	}
	else {
		removeFrameCallback(this.$moveFCB);
		delete this.$moveFCB;
		this.$handleActions();
	}
}

this.$doAnomaly = function() {
	var somethingToExplode = system.addShips("splinter", 1, this.visualEffect ,0 );
	somethingToExplode[0].explode();
	var thargoid = system.addShips("thargoid",1,this.visualEffect,50)[0];
	var arafura = system.shipsWithRole("arafura-mission",this.visualEffect,25600);
	if (arafura.length > 0) {
		arafura[0].target = thargoid;
		arafura[0].reactToAIMessage("THARGOIDS_ABOUT");
	}
	this.visualEffect.remove();
}
Scripts/rrsfl_arafura.js
"use strict";

this.author      = "spara"; 
this.copyright   = "2015 spara"; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Arafura rescue boat";
this.description = "Name ambiance arafuras the same way as mission arafuras and add support for escort formations oxp";

this.shipSpawned = function() {
	if (worldScripts["Escort Formations Randomiser"]) {
		worldScripts["Escort Formations Randomiser"].$setupDefensiveEscorts(this.ship);
	}
	this.wingName = expandDescription("[rescue_wingnames]");
	this.ship.displayName = this.ship.displayName + ": " + this.wingName + " Leader";
	if (this.ship.escorts) {
		for (var i = 0; i < this.ship.escorts.length; i++) {
			this.ship.escorts[i].displayName = this.ship.escorts[i].displayName + ": " + this.wingName + " " + (i+2);
		}
	}
}
Scripts/rrsfl_arafura_ind.js
"use strict";

this.author      = "spara"; 
this.copyright   = "2014 - 2015 spara"; 
this.licence = "CC-BY-SA 3.0";
this.name      = "Independent Arafura rescue boat";
this.description = "Add support for escort formations oxp";

this.shipSpawned = function() {
	if (worldScripts["Escort Formations Randomiser"]) {
		worldScripts["Escort Formations Randomiser"].$setupDefensiveEscorts(this.ship);
	};
}
Scripts/rrsfl_asteroid_ambusher.js
"use strict";

this.name               = "ambusher_script";
this.author               = "spara";
this.copyright            = "2014 - 2015 Mika Spåra";
this.description         = "RSS Ambusher shp script";
this.licence     = "CC BY-NC-SA 3.0";

//fixed ai
//Tumbling part from Smivs - 'rotateDerelict'. Code by Capt. Murphy.

this.shipSpawned = function() {
	this.rotateAmbushTimer = new Timer(this, this.rotateAmbush,3); // timer to start derelict rotation after 3 seconds
	delete this.shipSpawned;
}

this.rotateAmbush = function(){
 this.rotateVector = Vector3D.randomDirection(); // creates a random axis of rotation.
 this.rotateSpeedFactor = (Math.random() * (0.05) + 0.05); // creates a random rotate speed factor between 0.05 and 0.1 - 0.1 will result in a rotation speed of approx 1 full rotation every 63 seconds, 0.05 in a rotation speed of approx 1 full rotation every 126 seconds.
 this.rotateAmbushCallback = addFrameCallback(this.rotateFunction.bind(this)); // create FrameCallback
}

// delta is the time in game seconds since the last frame.
this.rotateFunction = function(delta) {
	if (!this.ship.isValid){
		removeFrameCallback(this.rotateAmbushCallback);
		delete this.rotateAmbushCallback;return;
	} // end FrameCallback is ship has died;
 if (delta === 0){return;} // do nothing if game is paused;
 var newOrientation = this.ship.orientation.rotate(this.rotateVector,delta*this.rotateSpeedFactor); // calculates new orientation, using delta as a factor so that rotation speed is constant across varying frame rates. delta*this.rotateSpeedFactor is a value in radians. There are approx 6.3 radians in a full rotation.
 this.ship.orientation = newOrientation; // applies new orientation;
}

this.activateAmbush = function() {
	
	//stop tumbling
	removeFrameCallback(this.rotateAmbushCallback);
	delete this.rotateAmbushCallback;
	//turn up the lights
	this.ship.subEntities[0].setMaterials({"bbs_sidewinder_emission.png": {diffuse_map: "rrsfl_asteroid_sidewinder_e.png", emission_map: "rrsfl_asteroid_sidewinder_emission-lights.png", emission_modulate_color: (255, 252, 200, 0.75)}}); //colors the cockpit, navlights and engines only
	//name her
	if (worldScripts.randomshipnames) 
		this.ship.displayName = this.ship.name + ": " + worldScripts.randomshipnames.$randomPirateName(this.ship);
	else this.ship.displayName = this.ship.name;
	//correct scan class
	this.ship.scanClass = "CLASS_NEUTRAL";
	//bring 'em on
	this.ship.switchAI("rescue-assassinAI.js");
}
Scripts/rrsfl_mining_outpost.js
"use strict";

this.author      = "spara"; 
this.copyright   = "2014 - 2015 spara"; 
this.licence = "CC-BY-SA 3.0";
this.name      = "mining_outpost_ship_script";
this.description = "Additional action to basic rock hermit AI.";

//Shooting the outpost or attacking ships near the outpost has concequences.

this.shipBeingAttacked = function(whom) {
	ship.target = whom;
	var defenseShip = this.ship.launchDefenseShip();
	if (defenseShip !== null) defenseShip.AIPrimaryAggressor = whom;
	if (whom === player) whom.bounty++;
}

this.distressMessageReceived = function(aggressor, sender) {
	ship.target = aggressor;
	var defenseShip = this.ship.launchDefenseShip();
	if (defenseShip !== null) defenseShip.AIPrimaryAggressor = aggressor;
	if (aggressor === player) aggressor.bounty++;
}
Scripts/rrsfl_mining_outpost_nc.js
"use strict";
this.name = "mining_outpost_new_cargoes";
this.author      = "spara"; 
this.copyright   = "2014 - 2015 spara"; 
this.licence = "CC-BY-SA 3.0";
this.description = "Mining outpost new cargoes market definition. NC Market is there only to buy.";

this.startUp = function() {
	if (!worldScripts.CargoTypeExtension) return;
	else 
		worldScripts["CargoTypeExtension"].registerOXPStation(this.name,"rrs-mining-outpost");
}

this.exportCargoAmount = function(good) {
		return 0;
}

this.exportCargoPrice = function(good) {
		return 1;
}

this.importCargoPrice = function(good) {
		return 1;
}

this.randomCargoAmount = function(good) {
		return 0;
} 

this.randomCargoChance = function(good) {
		return 0;
}

this.randomImportChance = function(good) {
		return 0.;
}

this.systemImportChance = function(good) {
		return 0;
}

this.importPermitCheck = function() {
		return false;
}

this.exportPermitCheck = function() {
		return false;
}

this.stationGossip = function() {
		return false;
}