Back to Index Page generated: Dec 1, 2024, 3:15:25 AM

Expansion Elite Trader Meta

Content

Warnings

  1. http://wiki.alioth.net/index.php/Elite%20Trader%20Meta -> 404 Not Found
  2. Low hanging fuit: Information URL exists...

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Already a meta-game, the Guild of Elite Traders subverts Galcop and turns everything toward Trade. Perks include anti-masslock, witchpoint refuel, a forever-clean record, constant ship-enhancement, bonuses, new ship, lodges, cloak, fast dock; and Market scores count toward Elite. Progress in Grade brings a further edge. But - do not kill! Elite Trader Meta is an all-inclusive package featuring: Elite Trader, Auxiliary Pylon, Cargo Pods 10-50 TC, Cargo Space Refit, FE Ships, GETter HUD, Goods Containers 10-50 TC, and Overdrive. Already a meta-game, the Guild of Elite Traders subverts Galcop and turns everything toward Trade. Perks include anti-masslock, witchpoint refuel, a forever-clean record, constant ship-enhancement, bonuses, new ship, lodges, cloak, fast dock; and Market scores count toward Elite. Progress in Grade brings a further edge. But - do not kill! Elite Trader Meta is an all-inclusive package featuring: Elite Trader, Auxiliary Pylon, Cargo Pods 10-50 TC, Cargo Space Refit, FE Ships, GETter HUD, Goods Containers 10-50 TC, and Overdrive.
Identifier oolite.oxp.Reval.Elite_Trader_Meta oolite.oxp.Reval.Elite_Trader_Meta
Title Elite Trader Meta Elite Trader Meta
Category Mechanics Mechanics
Author Reval Reval
Version 1.19.2 1.19.2
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/Elite_Trader_OXZ n/a
Download URL https://wiki.alioth.net/img_auth.php/4/40/Elite_Trader_Meta.oxz n/a
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1670336354

Documentation

Equipment

Name Visible Cost [deci-credits] Tech-Level
Cargo Pod 10 TC yes 100000 5+
Cargo Pod 20 TC yes 200000 5+
Cargo Pod 30 TC yes 300000 5+
Cargo Pod 40 TC yes 400000 5+
Cargo Pod 50 TC yes 500000 5+
Overdrive yes 70000 5+
Auxiliary Pylon yes 150000 5+
Cargo Space Refit yes 5000 5+
Hull Shroud yes 100000 10+
G.E.T. fast-docking facility no 50 1+
Goods Container 10 TC yes 100000 7+
Goods Container 20 TC yes 200000 7+
Goods Container 30 TC yes 300000 7+
Goods Container 40 TC yes 400000 7+
Goods Container 50 TC yes 500000 7+

Ships

Name
Constrictor II
Constrictor IIg
FE_constrictor2-player
gecko-player
Goods Container 10 TC
Goods Container 20 TC
Goods Container 30 TC
Goods Container 40 TC
Goods Container 50 TC
guild_lodge_template
G.E.T. Guild Lodge
krait-player
mamba-player
sidewinder-player
Viper Mk 1 FE
Viper Mk 2 FE

Models

This expansion declares no models. This may be related to warnings.

Scripts

Path
Scripts/aj_script.js
"use strict"
this.name = "Overdrive";
this.author = "Reval";
this.license = "CC-BY-NC-SA 4.0";
this.version = "1.4";
this.description = "FE Shipyards will re-route part of your Jump circuitry, linking it to your vehicle's velocity-controller. When full speed is set, J-drive will engage in a limited mode, similar in effect to an injector, but silent, fluid, faster, and without the attendant fuel-waste. We call it the O-drive. To disengage it, decelerate to below your normal top speed.";


this.shipWillLaunchFromStation = function() {
	// start monitor if O-D installed and connected
	if ((this.$ajConnected) && (player.ship.equipmentStatus ("EQ_AUTO_J") === "EQUIPMENT_OK")) {
		if(!this.$ajTimer) this.$ajTimer=new Timer(this,this._ajMonitorSpeed.bind(this),0,0.25);
		// note nominal maximum speed
		this.$ajMaxSpeed = player.ship.maxSpeed;
		// if E.T. present, use the Guild's enhanced speed
		if (this.$ajET)
			this.$ajETLast = worldScripts["Elite Trader"].$etLastSpeed;
	}
}


this.shipWillDockWithStation = function(station) {
	this._ajStopOverdrive();
}


this.shipDockedWithStation = function(station) {
	// prepare connect/disconnect options Interface
	var ps=player.ship;
	if (ps.equipmentStatus ("EQ_AUTO_J") === "EQUIPMENT_OK") 
		this._ajPrepOptions(station);
}


this.shipWillEnterWitchspace = function(cause) {
     // stop O-D before entering witchspace
	 this._ajStopOverdrive();
}


this.playerWillSaveGame = function() {
	// save connected status
	if (this.$ajConnected) var con=1; else var con=0;
	missionVariables.ajConnected = con;
}


this.startUPComplete = function() {
	// load connected status
	if (missionVariables.ajConnected != null) {
		var con=missionVariables.ajConnected;
		this.$ajConnected = (con == 1);
	}
	
}


this.startUp = function() {
	// is E.T. present?
	this.$ajET = false;
	if (worldScripts["Elite Trader"]) 
		this.$ajET = true;
	// record etLastSpeed
	this.$ajETLast = player.ship.maxSpeed;
	// O-drive connection switch
	this.$ajConnected = true;
	this.$ajEngaged = false;
	this.$ajMaxed = false;
	this.$ajFactor = 10.0;
	this.$ajMaxSpeed = 0.0;
	// for total reset (connect/disconnect)
	this.$ajNominal = player.ship.maxSpeed;
}


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	var ps = player.ship;
	if (equipment == "EQ_AUTO_J") {
		pc("Re-routing J-circuits for O-drive.",9);
		pc("Overdrive is operative.",9);
		// prepare connect/disconnect options 
		var sta = player.ship.dockedStation;			
		if (ps.equipmentStatus ("EQ_AUTO_J") === "EQUIPMENT_OK") 
			this._ajPrepOptions(sta);
	}	
}


this._ajAdjustSpeed = function() {
	if (!this.$ajEngaged)
		if (!this.$ajMaxed) {
			player.ship.maxSpeed*=this.$ajFactor;
			this.$ajMaxed = true;
			this.$ajEngaged=true;
		}
}


this._ajMonitorSpeed = function() {
	var pss = player.ship.speed;
	if (this.$ajEngaged) {
		// stop the O-drive if J-Drive engaged
		if (player.ship.torusEngaged) 
			this._ajStopOverdrive();
		// stop the O-drive if decelerated to marker
		if (pss < this.$ajMaxSpeed)
			this._ajStopOverdrive();
	} else {
		// start the O-drive
		if ((pss==this.$ajETLast) || (pss==this.$ajMaxSpeed)) {
			this._ajAdjustSpeed();
			player.consoleMessage("O-drive engaged.");
		}
	}
}


this._ajStopOverdrive = function() {
	if (this.$ajET)
		player.ship.maxSpeed = this.$ajETLast; else
		player.ship.maxSpeed=this.$ajMaxSpeed;
	this.$ajEngaged = false;
	this.$ajMaxed = false;
	player.consoleMessage("O-drive disengaged.");
}



// create Overdrive connection options  
this._ajPrepOptions = function(station) {
	station.setInterface("ajOpt",{
	title: "Your FE Shipyards O-drive connection options",
	category: "Your FE Shipyards",
	summary: "FE Shipyards offers the option to connect or disconnect your Overdrive. This will also act as a 'reset' in case of unexpected behaviour." ,
	callback: this._ajShowOptions.bind(this)
	});	
}


// show Overdrive connection options
this._ajShowOptions = function() {
	
	var parameters = new Object();
	
	parameters.title = "Overdrive Connection Options";
	
	parameters.message = "Connect or disconnect your Overdrive circuits? \n\n";
	
	parameters.choicesKey = "ajChoice";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_CONNECT") {
			this.$ajConnected = true;
			this.$ajEngaged = false;
			this.$ajMaxed = false;
			if (this.$ajET)
				this.$ajETLast = worldScripts["Elite Trader"].$etLastSpeed; else
				this.$ajMaxSpeed = this.$ajNominal;
			player.commsMessage("Overdrive is connected.");
		} else {
			this.$ajConnected = false;
			this.$ajEngaged = false;
			this.$ajMaxed = false;
			if (this.$ajET)
				this.$ajETLast = worldScripts["Elite Trader"].$etLastSpeed; else
				this.$ajMaxSpeed = this.$ajNominal;
			player.commsMessage("Overdrive is disconnected.");
		}
	}	
}

Scripts/ap_conditions.js
// conditions for award of Auxiliary Pylon
"use strict";
this.name = "AP Conditions";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";

this.allowAwardEquipment = function(equipment, ship, context) {
	
	if (equipment == "EQ_AUX_PYLON") return true;
	return true;
}
Scripts/ap_script.js
"use strict";
this.name = "Auxiliary Pylon";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_AUX_PYLON") {
			pc("Modifying underbelly for pylon attachment.",9);
			pc("Fitting one Auxiliary Pylon.",9);
	}	
}


this.equipmentRemoved = function(equipmentKey) {
    var pc=player.consoleMessage;
	if (equipmentKey == "EQ_AUX_PYLON") {
		pc("Auxiliary Pylon cannot be removed.",7);
	}
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
}
Scripts/autodock_conditions.js
"use strict";

this.allowAwardEquipment = function(equipment, ship, context) {
	if (context != "scripted") return false;
	return true
}
Scripts/cp1_conditions.js
// conditions for award of 10 TC Cargo Pod
"use strict";
this.name = "CP10 Conditions";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";

this.allowAwardEquipment = function(equipment, ship, context) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_10TC_POD") {
		// fittable only if auxiliary pylon is installed
		if (player.ship.equipmentStatus ("EQ_AUX_PYLON") === "EQUIPMENT_OK") {
			// and not displayed if any pod is already fitted
			if ((player.ship.equipmentStatus ("EQ_10TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_20TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_30TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_40TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_50TC_POD") !== "EQUIPMENT_OK"))
				return true; else return false;
		} else return false;
	}	
	return true;
}
Scripts/cp1_script.js
"use strict";
this.name = "Cargo Pod 10 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_10TC_POD") {		
		pc("Attaching one 10 TC Pod to auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity += 10;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
		// always 1 because only one pod can be fitted
		this.$cp1Pods=1;
	}	
}


this.equipmentRemoved = function(equipmentKey) {
    var pc=player.consoleMessage;
	if (equipmentKey == "EQ_10TC_POD") {
		pc("Detaching one 10 TC Pod from auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity -= 10;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
	}
}



this.startUpComplete = function () {
	var pc = player.consoleMessage;
	if (missionVariables.cp1Pods != null) 
		this.$cp1Pods = missionVariables.cp1Pods;
	// Load total fees taken
	if (missionVariables.cp1HandlingFeeTotal != null)
		this.$cp1HandlingFeeTotal = missionVariables.cp1HandlingFeeTotal;
	if (missionVariables.cp1HandlingPaid != null)
		this.$cp1HandlingPaid = missionVariables.cp1HandlingPaid;
	if (missionVariables.cp1MaintenanceFeeTotal != null)
		this.$cp1MaintenanceFeeTotal = missionVariables.cp1MaintenanceFeeTotal;
	if (missionVariables.cp1DismantlingFeeTotal != null)
		this.$cp1DismantlingFeeTotal = missionVariables.cp1DismantlingFeeTotal; 
    // Load system-to-system runs w/pod
	if (missionVariables.cp1Runs != null)
		this.$cp1Runs = missionVariables.cp1Runs;
	// Load Handling fee count
	if (missionVariables.cp1HandlingCount != null)
		this.$cp1HandlingCount = missionVariables.cp1HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.cp1HFExempt != null)
		this.$cp1HFExempt = missionVariables.cp1HFExempt;
	// Load Maintenance fee count
	if (missionVariables.cp1MaintenanceCount != null)
		this.$cp1MaintenanceCount = missionVariables.cp1MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// prepare pod Account screen
	var sta = player.ship.dockedStation;
	if (this.$cp1Pods>0) this._cp1PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$cp1Pods>0) this._cp1PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$cp1ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$cp1ET = true;
	// TEST	
	if (this.$cp1ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$cp1FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$cp1FES = true;
	// TEST	
	if (this.$cp1ET) log(this.name, "Finds FE Ships Player present");
	// number of pods - when fitted, always 1
	this.$cp1Pods = 0;
	// purchase cost of pod in cr
	this.$cp1Cost = 10000;
	// handling fee
	this.$cp1HandlingFee = 0.005*this.$cp1Cost; // 0.005 of cost
	this.$cp1HandlingFeeTotal = 0;
	this.$cp1HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$cp1HandlingCount = 0;
	this.$cp1HFExempt = "no";
	// maintenance fee
	this.$cp1MaintenanceFee = 0.05*this.$cp1Cost; // 0.05 of cost
	this.$cp1MaintenanceFeeTotal = 0;
	this.$cp1MaintenancePaid = "no" // or "yes"
	this.$cp1MaintenanceInterval = 10; // in runs (according to cost)
	this.$cp1MaintenanceCount = 0;
	// dismantling fee
	this.$cp1DismantlingFee = 0.1*this.$cp1Cost; // 0.1 of cost
	this.$cp1DismantlingFeeTotal = 0.0;
	// system-to-system runs w/pod
	this.$cp1Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.cp1Pods = this.$cp1Pods;
	// save total fees taken
	missionVariables.cp1HandlingFeeTotal = this.$cp1HandlingFeeTotal;
	missionVariables.cp1MaintenanceFeeTotal = this.$cp1MaintenanceFeeTotal;
	missionVariables.cp1DismantlingFeeTotal = this.$cp1DismantlingFeeTotal;
	missionVariables.cp1HandlingPaid = this.$cp1HandlingPaid;
	// system-to-system runs w/pod
	missionVariables.cp1Runs =this.$cp1Runs;
	// handling fee count
	missionVariables.cp1HandlingCount = this.$cp1HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.cp1HFExempt = this.$cp1HFExempt;
	// maintenance fee count
	missionVariables.cp1MaintenanceCount = this.$cp1MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$cp1HFExempt;
	// check we have pods, the fee is not paid, and we're not exempt
	if ((this.$cp1Pods>0) && (this.$cp1HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$cp1Pods; x++)
			fee += this.$cp1HandlingFee;
		// record fee and debit trader's account
		this.$cp1HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$cp1HandlingPaid = "yes";
		pc("10 TC Pod handling fees: "+fee+" cr",9);
		this.$cp1HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$cp1Pods>0) this._cp1DoMaintenance();
	
	// prepare pod Account and Licence page
	if (this.$cp1Pods>0) this._cp1PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$cp1Pods>0) this._cp1PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$cp1HandlingPaid = "no";
	this.$cp1Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._cp1DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$cp1Runs;
	var intv = this.$cp1MaintenanceInterval;
	var mfee = this.$cp1MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x pods
		var fee = 0;
		for (var x=1; x<= this.$cp1Pods; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$cp1MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("10 TC Pod Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$cp1MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._cp1PrepAcc = function(station) {
	station.setInterface("cp1Acc",{
	title: "Your FE Shipyards 10 TC Pod Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 10 TC Pod account screen shows terms, fees paid, load, and other useful information.",
	callback: this._cp1ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._cp1ShowAcc = function() {
	var hfc = this.$cp1HandlingCount;
	var mfc = this.$cp1MaintenanceCount;
	var mfi = this.$cp1MaintenanceInterval;
	var hft = this.$cp1HandlingFeeTotal;
	var mft = this.$cp1MaintenanceFeeTotal;
	var dft = this.$cp1DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$cp1Pods>0) 
		parameters.message +="Your Account and Licence for 10 TC Class Goods Pods x "+this.$cp1Pods+": \n\n"; 
	 else
		parameters.message +="You have no 10 TC Class Pods licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our pods are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Pod account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylon for weapons-use. \n";
	
	parameters.choicesKey = "cp1Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._cp1PrepEx = function(station) {
	station.setInterface("cp1Ex",{
	title: "Your FE Shipyards Pod Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 10-ton pod class." ,
	callback: this._cp1ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._cp1ShowEx = function() {
	var priv = ((this.$cp1ET)||(this.$cp1FES));
	var privo = "";
	if (this.$cp1FES) privo="FE shipowner";
	if (this.$cp1ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 10 TC pod fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "cp1YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$cp1HFExempt = "yes"; else this.$cp1HFExempt = "no";
		} else this.$cp1HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}
Scripts/cp2_conditions.js
// conditions for award of 20 TC Cargo Pod
"use strict";
this.name = "CP20 Conditions";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";

this.allowAwardEquipment = function(equipment, ship, context) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_20TC_POD") {
		// fittable only if auxiliary pylon is installed
		if (player.ship.equipmentStatus ("EQ_AUX_PYLON") === "EQUIPMENT_OK") {
			// and not displayed if any pod is already fitted
			if ((player.ship.equipmentStatus ("EQ_10TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_20TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_30TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_40TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_50TC_POD") !== "EQUIPMENT_OK"))
				return true; else return false;
		} else return false;
	}	
	return true;
}
Scripts/cp2_script.js
"use strict";
this.name = "Cargo Pod 20 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_20TC_POD") {		
		pc("Attaching one 20 TC Pod to auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity += 20;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
		// always 1 because only one pod can be fitted
		this.$cp2Pods=1;
	}	
}


this.equipmentRemoved = function(equipmentKey) {
    var pc=player.consoleMessage;
	if (equipmentKey == "EQ_20TC_POD") {
		pc("Detaching one 20 TC Pod from auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity -= 20;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
	}
}



this.startUpComplete = function () {
	var pc = player.consoleMessage;
	if (missionVariables.cp2Pods != null) 
		this.$cp2Pods = missionVariables.cp2Pods;
	// Load total fees taken
	if (missionVariables.cp2HandlingFeeTotal != null)
		this.$cp2HandlingFeeTotal = missionVariables.cp2HandlingFeeTotal;
	if (missionVariables.cp2HandlingPaid != null)
		this.$cp2HandlingPaid = missionVariables.cp2HandlingPaid;
	if (missionVariables.cp2MaintenanceFeeTotal != null)
		this.$cp2MaintenanceFeeTotal = missionVariables.cp2MaintenanceFeeTotal;
	if (missionVariables.cp2DismantlingFeeTotal != null)
		this.$cp2DismantlingFeeTotal = missionVariables.cp2DismantlingFeeTotal; 
    // Load system-to-system runs w/pod
	if (missionVariables.cp2Runs != null)
		this.$cp2Runs = missionVariables.cp2Runs;
	// Load Handling fee count
	if (missionVariables.cp2HandlingCount != null)
		this.$cp2HandlingCount = missionVariables.cp2HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.cp2HFExempt != null)
		this.$cp2HFExempt = missionVariables.cp2HFExempt;
	// Load Maintenance fee count
	if (missionVariables.cp2MaintenanceCount != null)
		this.$cp2MaintenanceCount = missionVariables.cp2MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// prepare pod Account screen
	var sta = player.ship.dockedStation;
	if (this.$cp2Pods>0) this._cp2PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$cp2Pods>0) this._cp2PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$cp2ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$cp2ET = true;
	// TEST	
	if (this.$cp2ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$cp2FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$cp2FES = true;
	// TEST	
	if (this.$cp2ET) log(this.name, "Finds FE Ships Player present");
	// number of pods - when fitted, always 1
	this.$cp2Pods = 0;
	// purchase cost of pod in cr
	this.$cp2Cost = 20000;
	// handling fee
	this.$cp2HandlingFee = 0.005*this.$cp2Cost; // 0.005 of cost
	this.$cp2HandlingFeeTotal = 0;
	this.$cp2HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$cp2HandlingCount = 0;
	this.$cp2HFExempt = "no";
	// maintenance fee
	this.$cp2MaintenanceFee = 0.05*this.$cp2Cost; // 0.05 of cost
	this.$cp2MaintenanceFeeTotal = 0;
	this.$cp2MaintenancePaid = "no" // or "yes"
	this.$cp2MaintenanceInterval = 20; // in runs (according to cost)
	this.$cp2MaintenanceCount = 0;
	// dismantling fee
	this.$cp2DismantlingFee = 0.1*this.$cp2Cost; // 0.1 of cost
	this.$cp2DismantlingFeeTotal = 0.0;
	// system-to-system runs w/pod
	this.$cp2Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.cp2Pods = this.$cp2Pods;
	// save total fees taken
	missionVariables.cp2HandlingFeeTotal = this.$cp2HandlingFeeTotal;
	missionVariables.cp2MaintenanceFeeTotal = this.$cp2MaintenanceFeeTotal;
	missionVariables.cp2DismantlingFeeTotal = this.$cp2DismantlingFeeTotal;
	missionVariables.cp2HandlingPaid = this.$cp2HandlingPaid;
	// system-to-system runs w/pod
	missionVariables.cp2Runs =this.$cp2Runs;
	// handling fee count
	missionVariables.cp2HandlingCount = this.$cp2HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.cp2HFExempt = this.$cp2HFExempt;
	// maintenance fee count
	missionVariables.cp2MaintenanceCount = this.$cp2MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$cp2HFExempt;
	// check we have pods, the fee is not paid, and we're not exempt
	if ((this.$cp2Pods>0) && (this.$cp2HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$cp2Pods; x++)
			fee += this.$cp2HandlingFee;
		// record fee and debit trader's account
		this.$cp2HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$cp2HandlingPaid = "yes";
		pc("20 TC Pod handling fees: "+fee+" cr",9);
		this.$cp2HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$cp2Pods>0) this._cp2DoMaintenance();
	
	// prepare pod Account and Licence page
	if (this.$cp2Pods>0) this._cp2PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$cp2Pods>0) this._cp2PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$cp2HandlingPaid = "no";
	this.$cp2Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._cp2DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$cp2Runs;
	var intv = this.$cp2MaintenanceInterval;
	var mfee = this.$cp2MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x pods
		var fee = 0;
		for (var x=1; x<= this.$cp2Pods; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$cp2MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("20 TC Pod Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$cp2MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._cp2PrepAcc = function(station) {
	station.setInterface("cp2Acc",{
	title: "Your FE Shipyards 20 TC Pod Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 20 TC Pod account screen shows terms, fees paid, load, and other useful information.",
	callback: this._cp2ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._cp2ShowAcc = function() {
	var hfc = this.$cp2HandlingCount;
	var mfc = this.$cp2MaintenanceCount;
	var mfi = this.$cp2MaintenanceInterval;
	var hft = this.$cp2HandlingFeeTotal;
	var mft = this.$cp2MaintenanceFeeTotal;
	var dft = this.$cp2DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$cp2Pods>0) 
		parameters.message +="Your Account and Licence for 20 TC Class Goods Pods x "+this.$cp2Pods+": \n\n"; 
	 else
		parameters.message +="You have no 20 TC Class Pods licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our pods are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Pod account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylon for weapons-use. \n";
	
	parameters.choicesKey = "cp2Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._cp2PrepEx = function(station) {
	station.setInterface("cp2Ex",{
	title: "Your FE Shipyards Pod Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 20-ton pod class." ,
	callback: this._cp2ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._cp2ShowEx = function() {
	var priv = ((this.$cp2ET)||(this.$cp2FES));
	var privo = "";
	if (this.$cp2FES) privo="FE shipowner";
	if (this.$cp2ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 20 TC pod fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "cp2YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$cp2HFExempt = "yes"; else this.$cp2HFExempt = "no";
		} else this.$cp2HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}
Scripts/cp3_conditions.js
// conditions for award of 30 TC Cargo Pod
"use strict";
this.name = "CP30 Conditions";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";

this.allowAwardEquipment = function(equipment, ship, context) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_30TC_POD") {
		// fittable only if auxiliary pylon is installed
		if (player.ship.equipmentStatus ("EQ_AUX_PYLON") === "EQUIPMENT_OK") {
			// and not displayed if any pod is already fitted
			if ((player.ship.equipmentStatus ("EQ_10TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_20TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_30TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_40TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_50TC_POD") !== "EQUIPMENT_OK"))
				return true; else return false;
		} else return false;
	}	
	return true;
}
Scripts/cp3_script.js
"use strict";
this.name = "Cargo Pod 30 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_30TC_POD") {		
		pc("Attaching one 30 TC Pod to auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity += 30;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
		// always 1 because only one pod can be fitted
		this.$cp3Pods=1;
	}	
}


this.equipmentRemoved = function(equipmentKey) {
    var pc=player.consoleMessage;
	if (equipmentKey == "EQ_30TC_POD") {
		pc("Detaching one 30 TC Pod from auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity -= 30;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
	}
}



this.startUpComplete = function () {
	var pc = player.consoleMessage;
	if (missionVariables.cp3Pods != null) 
		this.$cp3Pods = missionVariables.cp3Pods;
	// Load total fees taken
	if (missionVariables.cp3HandlingFeeTotal != null)
		this.$cp3HandlingFeeTotal = missionVariables.cp3HandlingFeeTotal;
	if (missionVariables.cp3HandlingPaid != null)
		this.$cp3HandlingPaid = missionVariables.cp3HandlingPaid;
	if (missionVariables.cp3MaintenanceFeeTotal != null)
		this.$cp3MaintenanceFeeTotal = missionVariables.cp3MaintenanceFeeTotal;
	if (missionVariables.cp3DismantlingFeeTotal != null)
		this.$cp3DismantlingFeeTotal = missionVariables.cp3DismantlingFeeTotal; 
    // Load system-to-system runs w/pod
	if (missionVariables.cp3Runs != null)
		this.$cp3Runs = missionVariables.cp3Runs;
	// Load Handling fee count
	if (missionVariables.cp3HandlingCount != null)
		this.$cp3HandlingCount = missionVariables.cp3HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.cp3HFExempt != null)
		this.$cp3HFExempt = missionVariables.cp3HFExempt;
	// Load Maintenance fee count
	if (missionVariables.cp3MaintenanceCount != null)
		this.$cp3MaintenanceCount = missionVariables.cp3MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// prepare pod Account screen
	var sta = player.ship.dockedStation;
	if (this.$cp3Pods>0) this._cp3PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$cp3Pods>0) this._cp3PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$cp3ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$cp3ET = true;
	// TEST	
	if (this.$cp3ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$cp3FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$cp3FES = true;
	// TEST	
	if (this.$cp3ET) log(this.name, "Finds FE Ships Player present");
	// number of pods - when fitted, always 1
	this.$cp3Pods = 0;
	// purchase cost of pod in cr
	this.$cp3Cost = 30000;
	// handling fee
	this.$cp3HandlingFee = 0.005*this.$cp3Cost; // 0.005 of cost
	this.$cp3HandlingFeeTotal = 0;
	this.$cp3HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$cp3HandlingCount = 0;
	this.$cp3HFExempt = "no";
	// maintenance fee
	this.$cp3MaintenanceFee = 0.05*this.$cp3Cost; // 0.05 of cost
	this.$cp3MaintenanceFeeTotal = 0;
	this.$cp3MaintenancePaid = "no" // or "yes"
	this.$cp3MaintenanceInterval = 30; // in runs (according to cost)
	this.$cp3MaintenanceCount = 0;
	// dismantling fee
	this.$cp3DismantlingFee = 0.1*this.$cp3Cost; // 0.1 of cost
	this.$cp3DismantlingFeeTotal = 0.0;
	// system-to-system runs w/pod
	this.$cp3Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.cp3Pods = this.$cp3Pods;
	// save total fees taken
	missionVariables.cp3HandlingFeeTotal = this.$cp3HandlingFeeTotal;
	missionVariables.cp3MaintenanceFeeTotal = this.$cp3MaintenanceFeeTotal;
	missionVariables.cp3DismantlingFeeTotal = this.$cp3DismantlingFeeTotal;
	missionVariables.cp3HandlingPaid = this.$cp3HandlingPaid;
	// system-to-system runs w/pod
	missionVariables.cp3Runs =this.$cp3Runs;
	// handling fee count
	missionVariables.cp3HandlingCount = this.$cp3HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.cp3HFExempt = this.$cp3HFExempt;
	// maintenance fee count
	missionVariables.cp3MaintenanceCount = this.$cp3MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$cp3HFExempt;
	// check we have pods, the fee is not paid, and we're not exempt
	if ((this.$cp3Pods>0) && (this.$cp3HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$cp3Pods; x++)
			fee += this.$cp3HandlingFee;
		// record fee and debit trader's account
		this.$cp3HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$cp3HandlingPaid = "yes";
		pc("30 TC Pod handling fees: "+fee+" cr",9);
		this.$cp3HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$cp3Pods>0) this._cp3DoMaintenance();
	
	// prepare pod Account and Licence page
	if (this.$cp3Pods>0) this._cp3PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$cp3Pods>0) this._cp3PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$cp3HandlingPaid = "no";
	this.$cp3Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._cp3DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$cp3Runs;
	var intv = this.$cp3MaintenanceInterval;
	var mfee = this.$cp3MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x pods
		var fee = 0;
		for (var x=1; x<= this.$cp3Pods; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$cp3MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("30 TC Pod Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$cp3MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._cp3PrepAcc = function(station) {
	station.setInterface("cp3Acc",{
	title: "Your FE Shipyards 30 TC Pod Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 30 TC Pod account screen shows terms, fees paid, load, and other useful information.",
	callback: this._cp3ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._cp3ShowAcc = function() {
	var hfc = this.$cp3HandlingCount;
	var mfc = this.$cp3MaintenanceCount;
	var mfi = this.$cp3MaintenanceInterval;
	var hft = this.$cp3HandlingFeeTotal;
	var mft = this.$cp3MaintenanceFeeTotal;
	var dft = this.$cp3DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$cp3Pods>0) 
		parameters.message +="Your Account and Licence for 30 TC Class Goods Pods x "+this.$cp3Pods+": \n\n"; 
	 else
		parameters.message +="You have no 30 TC Class Pods licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our pods are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Pod account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylon for weapons-use. \n";
	
	parameters.choicesKey = "cp3Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._cp3PrepEx = function(station) {
	station.setInterface("cp3Ex",{
	title: "Your FE Shipyards Pod Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 30-ton pod class." ,
	callback: this._cp3ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._cp3ShowEx = function() {
	var priv = ((this.$cp3ET)||(this.$cp3FES));
	var privo = "";
	if (this.$cp3FES) privo="FE shipowner";
	if (this.$cp3ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 30 TC pod fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "cp3YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$cp3HFExempt = "yes"; else this.$cp3HFExempt = "no";
		} else this.$cp3HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}
Scripts/cp4_conditions.js
// conditions for award of 40 TC Cargo Pod
"use strict";
this.name = "CP40 Conditions";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";

this.allowAwardEquipment = function(equipment, ship, context) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_40TC_POD") {
		// fittable only if auxiliary pylon is installed
		if (player.ship.equipmentStatus ("EQ_AUX_PYLON") === "EQUIPMENT_OK") {
			// and not displayed if any pod is already fitted
			if ((player.ship.equipmentStatus ("EQ_10TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_20TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_30TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_40TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_50TC_POD") !== "EQUIPMENT_OK"))
				return true; else return false;
		} else return false;
	}	
	return true;
}
Scripts/cp4_script.js
"use strict";
this.name = "Cargo Pod 40 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_40TC_POD") {		
		pc("Attaching one 40 TC Pod to auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity += 40;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
		// always 1 because only one pod can be fitted
		this.$cp4Pods=1;
	}	
}


this.equipmentRemoved = function(equipmentKey) {
    var pc=player.consoleMessage;
	if (equipmentKey == "EQ_40TC_POD") {
		pc("Detaching one 40 TC Pod from auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity -= 40;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
	}
}



this.startUpComplete = function () {
	var pc = player.consoleMessage;
	if (missionVariables.cp4Pods != null) 
		this.$cp4Pods = missionVariables.cp4Pods;
	// Load total fees taken
	if (missionVariables.cp4HandlingFeeTotal != null)
		this.$cp4HandlingFeeTotal = missionVariables.cp4HandlingFeeTotal;
	if (missionVariables.cp4HandlingPaid != null)
		this.$cp4HandlingPaid = missionVariables.cp4HandlingPaid;
	if (missionVariables.cp4MaintenanceFeeTotal != null)
		this.$cp4MaintenanceFeeTotal = missionVariables.cp4MaintenanceFeeTotal;
	if (missionVariables.cp4DismantlingFeeTotal != null)
		this.$cp4DismantlingFeeTotal = missionVariables.cp4DismantlingFeeTotal; 
    // Load system-to-system runs w/pod
	if (missionVariables.cp4Runs != null)
		this.$cp4Runs = missionVariables.cp4Runs;
	// Load Handling fee count
	if (missionVariables.cp4HandlingCount != null)
		this.$cp4HandlingCount = missionVariables.cp4HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.cp4HFExempt != null)
		this.$cp4HFExempt = missionVariables.cp4HFExempt;
	// Load Maintenance fee count
	if (missionVariables.cp4MaintenanceCount != null)
		this.$cp4MaintenanceCount = missionVariables.cp4MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// prepare pod Account screen
	var sta = player.ship.dockedStation;
	if (this.$cp4Pods>0) this._cp4PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$cp4Pods>0) this._cp4PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$cp4ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$cp4ET = true;
	// TEST	
	if (this.$cp4ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$cp4FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$cp4FES = true;
	// TEST	
	if (this.$cp4ET) log(this.name, "Finds FE Ships Player present");
	// number of pods - when fitted, always 1
	this.$cp4Pods = 0;
	// purchase cost of pod in cr
	this.$cp4Cost = 40000;
	// handling fee
	this.$cp4HandlingFee = 0.005*this.$cp4Cost; // 0.005 of cost
	this.$cp4HandlingFeeTotal = 0;
	this.$cp4HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$cp4HandlingCount = 0;
	this.$cp4HFExempt = "no";
	// maintenance fee
	this.$cp4MaintenanceFee = 0.05*this.$cp4Cost; // 0.05 of cost
	this.$cp4MaintenanceFeeTotal = 0;
	this.$cp4MaintenancePaid = "no" // or "yes"
	this.$cp4MaintenanceInterval = 40; // in runs (according to cost)
	this.$cp4MaintenanceCount = 0;
	// dismantling fee
	this.$cp4DismantlingFee = 0.1*this.$cp4Cost; // 0.1 of cost
	this.$cp4DismantlingFeeTotal = 0.0;
	// system-to-system runs w/pod
	this.$cp4Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.cp4Pods = this.$cp4Pods;
	// save total fees taken
	missionVariables.cp4HandlingFeeTotal = this.$cp4HandlingFeeTotal;
	missionVariables.cp4MaintenanceFeeTotal = this.$cp4MaintenanceFeeTotal;
	missionVariables.cp4DismantlingFeeTotal = this.$cp4DismantlingFeeTotal;
	missionVariables.cp4HandlingPaid = this.$cp4HandlingPaid;
	// system-to-system runs w/pod
	missionVariables.cp4Runs =this.$cp4Runs;
	// handling fee count
	missionVariables.cp4HandlingCount = this.$cp4HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.cp4HFExempt = this.$cp4HFExempt;
	// maintenance fee count
	missionVariables.cp4MaintenanceCount = this.$cp4MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$cp4HFExempt;
	// check we have pods, the fee is not paid, and we're not exempt
	if ((this.$cp4Pods>0) && (this.$cp4HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$cp4Pods; x++)
			fee += this.$cp4HandlingFee;
		// record fee and debit trader's account
		this.$cp4HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$cp4HandlingPaid = "yes";
		pc("40 TC Pod handling fees: "+fee+" cr",9);
		this.$cp4HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$cp4Pods>0) this._cp4DoMaintenance();
	
	// prepare pod Account and Licence page
	if (this.$cp4Pods>0) this._cp4PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$cp4Pods>0) this._cp4PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$cp4HandlingPaid = "no";
	this.$cp4Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._cp4DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$cp4Runs;
	var intv = this.$cp4MaintenanceInterval;
	var mfee = this.$cp4MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x pods
		var fee = 0;
		for (var x=1; x<= this.$cp4Pods; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$cp4MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("40 TC Pod Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$cp4MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._cp4PrepAcc = function(station) {
	station.setInterface("cp4Acc",{
	title: "Your FE Shipyards 40 TC Pod Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 40 TC Pod account screen shows terms, fees paid, load, and other useful information.",
	callback: this._cp4ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._cp4ShowAcc = function() {
	var hfc = this.$cp4HandlingCount;
	var mfc = this.$cp4MaintenanceCount;
	var mfi = this.$cp4MaintenanceInterval;
	var hft = this.$cp4HandlingFeeTotal;
	var mft = this.$cp4MaintenanceFeeTotal;
	var dft = this.$cp4DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$cp4Pods>0) 
		parameters.message +="Your Account and Licence for 40 TC Class Goods Pods x "+this.$cp4Pods+": \n\n"; 
	 else
		parameters.message +="You have no 40 TC Class Pods licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our pods are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Pod account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylon for weapons-use. \n";
	
	parameters.choicesKey = "cp4Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._cp4PrepEx = function(station) {
	station.setInterface("cp4Ex",{
	title: "Your FE Shipyards Pod Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 40-ton pod class." ,
	callback: this._cp4ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._cp4ShowEx = function() {
	var priv = ((this.$cp4ET)||(this.$cp4FES));
	var privo = "";
	if (this.$cp4FES) privo="FE shipowner";
	if (this.$cp4ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 40 TC pod fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "cp4YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$cp4HFExempt = "yes"; else this.$cp4HFExempt = "no";
		} else this.$cp4HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}
Scripts/cp5_conditions.js
// conditions for award of 50 TC Cargo Pod
"use strict";
this.name = "CP50 Conditions";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";

this.allowAwardEquipment = function(equipment, ship, context) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_50TC_POD") {
		// fittable only if auxiliary pylon is installed
		if (player.ship.equipmentStatus ("EQ_AUX_PYLON") === "EQUIPMENT_OK") {
			// and not displayed if any pod is already fitted
			if ((player.ship.equipmentStatus ("EQ_10TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_20TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_30TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_40TC_POD") !== "EQUIPMENT_OK") && (player.ship.equipmentStatus ("EQ_50TC_POD") !== "EQUIPMENT_OK"))
				return true; else return false;
		} else return false;
	}	
	return true;
}
Scripts/cp5_script.js
"use strict";
this.name = "Cargo Pod 50 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_50TC_POD") {		
		pc("Attaching one 50 TC Pod to auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity += 50;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
		// always 1 because only one pod can be fitted
		this.$cp5Pods=1;
	}	
}


this.equipmentRemoved = function(equipmentKey) {
    var pc=player.consoleMessage;
	if (equipmentKey == "EQ_50TC_POD") {
		pc("Detaching one 50 TC Pod from auxiliary pylon.",9);
		player.ship.cargoSpaceCapacity -= 50;
		pc("Ship's total capacity = "+player.ship.cargoSpaceCapacity+" TC.",9);
	}
}



this.startUpComplete = function () {
	var pc = player.consoleMessage;
	if (missionVariables.cp5Pods != null) 
		this.$cp5Pods = missionVariables.cp5Pods;
	// Load total fees taken
	if (missionVariables.cp5HandlingFeeTotal != null)
		this.$cp5HandlingFeeTotal = missionVariables.cp5HandlingFeeTotal;
	if (missionVariables.cp5HandlingPaid != null)
		this.$cp5HandlingPaid = missionVariables.cp5HandlingPaid;
	if (missionVariables.cp5MaintenanceFeeTotal != null)
		this.$cp5MaintenanceFeeTotal = missionVariables.cp5MaintenanceFeeTotal;
	if (missionVariables.cp5DismantlingFeeTotal != null)
		this.$cp5DismantlingFeeTotal = missionVariables.cp5DismantlingFeeTotal; 
    // Load system-to-system runs w/pod
	if (missionVariables.cp5Runs != null)
		this.$cp5Runs = missionVariables.cp5Runs;
	// Load Handling fee count
	if (missionVariables.cp5HandlingCount != null)
		this.$cp5HandlingCount = missionVariables.cp5HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.cp5HFExempt != null)
		this.$cp5HFExempt = missionVariables.cp5HFExempt;
	// Load Maintenance fee count
	if (missionVariables.cp5MaintenanceCount != null)
		this.$cp5MaintenanceCount = missionVariables.cp5MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// prepare pod Account screen
	var sta = player.ship.dockedStation;
	if (this.$cp5Pods>0) this._cp5PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$cp5Pods>0) this._cp5PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$cp5ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$cp5ET = true;
	// TEST	
	if (this.$cp5ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$cp5FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$cp5FES = true;
	// TEST	
	if (this.$cp5ET) log(this.name, "Finds FE Ships Player present");
	// number of pods - when fitted, always 1
	this.$cp5Pods = 0;
	// purchase cost of pod in cr
	this.$cp5Cost = 50000;
	// handling fee
	this.$cp5HandlingFee = 0.005*this.$cp5Cost; // 0.005 of cost
	this.$cp5HandlingFeeTotal = 0;
	this.$cp5HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$cp5HandlingCount = 0;
	this.$cp5HFExempt = "no";
	// maintenance fee
	this.$cp5MaintenanceFee = 0.05*this.$cp5Cost; // 0.05 of cost
	this.$cp5MaintenanceFeeTotal = 0;
	this.$cp5MaintenancePaid = "no" // or "yes"
	this.$cp5MaintenanceInterval = 50; // in runs (according to cost)
	this.$cp5MaintenanceCount = 0;
	// dismantling fee
	this.$cp5DismantlingFee = 0.1*this.$cp5Cost; // 0.1 of cost
	this.$cp5DismantlingFeeTotal = 0.0;
	// system-to-system runs w/pod
	this.$cp5Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.cp5Pods = this.$cp5Pods;
	// save total fees taken
	missionVariables.cp5HandlingFeeTotal = this.$cp5HandlingFeeTotal;
	missionVariables.cp5MaintenanceFeeTotal = this.$cp5MaintenanceFeeTotal;
	missionVariables.cp5DismantlingFeeTotal = this.$cp5DismantlingFeeTotal;
	missionVariables.cp5HandlingPaid = this.$cp5HandlingPaid;
	// system-to-system runs w/pod
	missionVariables.cp5Runs =this.$cp5Runs;
	// handling fee count
	missionVariables.cp5HandlingCount = this.$cp5HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.cp5HFExempt = this.$cp5HFExempt;
	// maintenance fee count
	missionVariables.cp5MaintenanceCount = this.$cp5MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$cp5HFExempt;
	// check we have pods, the fee is not paid, and we're not exempt
	if ((this.$cp5Pods>0) && (this.$cp5HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$cp5Pods; x++)
			fee += this.$cp5HandlingFee;
		// record fee and debit trader's account
		this.$cp5HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$cp5HandlingPaid = "yes";
		pc("50 TC Pod handling fees: "+fee+" cr",9);
		this.$cp5HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$cp5Pods>0) this._cp5DoMaintenance();
	
	// prepare pod Account and Licence page
	if (this.$cp5Pods>0) this._cp5PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$cp5Pods>0) this._cp5PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$cp5HandlingPaid = "no";
	this.$cp5Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._cp5DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$cp5Runs;
	var intv = this.$cp5MaintenanceInterval;
	var mfee = this.$cp5MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x pods
		var fee = 0;
		for (var x=1; x<= this.$cp5Pods; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$cp5MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("50 TC Pod Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$cp5MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._cp5PrepAcc = function(station) {
	station.setInterface("cp5Acc",{
	title: "Your FE Shipyards 50 TC Pod Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 50 TC Pod account screen shows terms, fees paid, load, and other useful information.",
	callback: this._cp5ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._cp5ShowAcc = function() {
	var hfc = this.$cp5HandlingCount;
	var mfc = this.$cp5MaintenanceCount;
	var mfi = this.$cp5MaintenanceInterval;
	var hft = this.$cp5HandlingFeeTotal;
	var mft = this.$cp5MaintenanceFeeTotal;
	var dft = this.$cp5DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$cp5Pods>0) 
		parameters.message +="Your Account and Licence for 50 TC Class Goods Pods x "+this.$cp5Pods+": \n\n"; 
	 else
		parameters.message +="You have no 50 TC Class Pods licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our pods are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Pod account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylon for weapons-use. \n";
	
	parameters.choicesKey = "cp5Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._cp5PrepEx = function(station) {
	station.setInterface("cp5Ex",{
	title: "Your FE Shipyards Pod Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 50-ton pod class." ,
	callback: this._cp5ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._cp5ShowEx = function() {
	var priv = ((this.$cp5ET)||(this.$cp5FES));
	var privo = "";
	if (this.$cp5FES) privo="FE shipowner";
	if (this.$cp5ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 50 TC pod fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "cp5YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$cp5HFExempt = "yes"; else this.$cp5HFExempt = "no";
		} else this.$cp5HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}
Scripts/csr_conditions.js
// conditions for award of Cargo Space Refit
"use strict";
this.name = "CSR Conditions";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";

this.allowAwardEquipment = function(equipment, ship, context) {
	
	if (equipment == "EQ_CARGO_REFIT") {
		var charges = 0, csc = 0;
		// if containers are fitted, this will include their capacity
		// so the refit should be ordered before fitting them
		var csc = ship.cargoSpaceCapacity;
		for (var i=1; i<=csc; i++) charges += 500;
		if (player.credits>=charges) return true;
			else return false;
	}
	return true;
}
Scripts/csr_script.js
"use strict";
this.name = "Cargo Space Refit";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	if (equipment == "EQ_CARGO_REFIT") {
		if (this.$csrFitted=="no") {
			// increase space by ship's nominal capacity
			player.ship.cargoSpaceCapacity += this.$csrNominal;
			var pcc=player.ship.cargoSpaceCapacity;
			pc("Refitting ship to "+pcc+" TC capacity...",9);
			this.$csrSpace = pcc;
			// charge refit fee according to ship size
			for (var i=1; i<= this.$csrNominal; i++)
				this.$csrCharges += 500;
			// debit customer's account
			// note: player.credits won't go into the red!
			player.credits -= this.$csrCharges;
			// reimburse deposit
			var pd = paid/10; // decicredits, so convert
			this.$csrDeposit = pd;
			player.credits += pd;
			pc("Total cost: "+this.$csrCharges+" cr",9);
			pc("F4 to check your invoice.",9);
			this.$csrFitted = "yes";
			// prepare Invoice Interface
			var sta = player.ship.dockedStation;			
			this._csrPrepInv(sta);
		} else pc("Ship already refitted.",7);
	}	
}


this.equipmentRemoved = function(equipmentKey) {
    var pc=player.consoleMessage;
	if (equipmentKey == "EQ_CARGO_REFIT") {
		pc("We cannot un-refit your ship!",7);
	}
}


this.playerBoughtNewShip = function(ship, price) {
	var pc = player.consoleMessage;
	// reset csr globals and note new capacity
	this.$csrNominal = ship.cargoSpaceCapacity;
	this.$csrSpace = 0;
	this.$csrFitted = "no";
	this.$csrCharges = 0;
	this.$csrDeposit = 0;	
}


this.shipDockedWithStation = function(station) {
	// conditionally, prepare Invoice Interface
	if (this.$csrFitted=="yes")	this._csrPrepInv(station);
}


this.startUpComplete = function () {
	var pc = player.consoleMessage;
	if (missionVariables.csrSpace != null) 
		player.ship.cargoSpaceCapacity += missionVariables.csrSpace;
	if (missionVariables.csrFitted != null) 
		this.$csrFitted = missionVariables.csrFitted;
	if (missionVariables.csrCharges != null) 
		this.$csrCharges = missionVariables.csrCharges;
	if (missionVariables.csrDeposit != null) 
		this.$csrDeposit = missionVariables.csrDeposit;
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	this.$csrSpace = 0;
	this.$csrFitted = "no";
	// record nominal capacity in case Containers are present
	this.$csrNominal = player.ship.cargoSpaceCapacity;
	// initialize charges
	this.$csrCharges = 0;
	// initialize deposit
	this.$csrDeposit = 0;	
}


this.playerWillSaveGame = function(message) {
	missionVariables.csrSpace = this.$csrSpace;
	missionVariables.csrFitted = this.$csrFitted;
	missionVariables.csrCharges = this.$csrCharges;
	missionVariables.csrDeposit = this.$csrDeposit;
}


// create F.E.S. Cargo Space Invoice sheet  
this._csrPrepInv = function(station) {
	station.setInterface("csrInv",{
	title: "Your FE Shipyards Invoice for CSR work",
	category: "Your FE Shipyards",
	summary: "FE Shipyards invites you to check your Invoice for the recent Cargo Space Refit undertaken on your behalf." ,
	callback: this._csrShowInv.bind(this)
	});	
}


// show F.E.S. Invoice for Cargo Space Refit
this._csrShowInv = function() {
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards Invoice for Cargo Space Refit";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "This constitutes your invoice for our successful cargo space refit recently undertaken on your "+player.ship.name+" with nominal capacity "+this.$csrNominal+"  TC.\n\n";
	
	parameters.message += "Total Charges: "+this.$csrCharges+" cr \n\n";
	
	parameters.message += "The amount debited from your account includes your initial deposit of "+ this.$csrDeposit + " cr. \n\n";
	
	parameters.message += "We count, as always, on your satisfaction with our service.\n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "csrAcknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")
			player.commsMessage("FE Shipyards thanks you for your custom.");
	}	
}

Scripts/et_equipment_conditions.js
"use strict";

this.allowAwardEquipment = function(equipment, ship, context) {
	//if (context != "scripted") return false;
	
	if (equipment == "EQ_ET_AUTODOCK") return true;
	if (equipment == "EQ_CLOAKING_DEVICE") return true;
	if (equipment == "EQ_HULL_SHROUD") return true;

	return true;
}
Scripts/et_hull_shroud_device.js
/*
FE Shipyards hull shroud
*/

"use strict";

this.name = "Hull Shroud";
this.author	= "Reval";


this.activated = function()
{
	player.ship.isCloaked = !player.ship.isCloaked;
	
	var hs = player.ship.isCloaked;
	var pc = player.commsMessage;
	var ac = "";
	if (hs) ac="ACTIVE"; else ac="inactive";
	pc("Hull shroud "+ac,9);
}
Scripts/et_script.js
"use strict";

this.name = "Elite Trader";
this.author = "Reval";
this.description = "Already a meta-game, the Guild of Elite Traders subverts Galcop and turns everything toward Trade. Perks include anti-masslock, witchpoint refuel, a forever-clean record, constant ship-enhancement, bonuses, new ship, lodges, cloak, fast dock; and Market scores count toward Elite. Progress in Grade brings a further edge. But - do not kill!";
this.license = "CC-BY-NC-SA 4.0";
this.version = "1.19.2";


/* 

  Version 1.19.1
  --------------
  
  * A minor revision of the conditions for showing the "noob Grocer" text under G.E.T. Master Advisory. Previously dependent on the number of runs (6), now, once the Grocer has read and acknowleged the introductory text, G.E.T.'s Master Advisory reverts to its true purpose of displaying the buy-prices of the system's primary commodities.
  
  
  Version 1.19
  ------------

 * Upon docking at a Lodge, G.E.T. will pay a <b>Boon of 100 cr</b> in appreciation of your patronage of the system's principal Guild Home.
 * A new <b>F4 Interface</b> exclusive to the Lodge: the "<u>G.E.T. Guild Lodge Sales Advisory</u>", showing sell prices for the two most traded goods at all stations insystem. Those above the Apprentice grade may go on availing themselves of the <u>Witchpoint Trade Advisory</u> (giving only the single most-traded commodity prices), still a somewhat quicker option for the impatient trader.
 * NPC traffic will now be encountered going into and out of the Guild Lodge - assume most of these ships are Elite Traders!
 * Lodge Guardian Constrictor IIg craft will now respond to <b>S.O.S. signals</b> from beleaguered vessels, along with any Galcop police present.
 * Lodge-tailored <b>welcome messages</b> appear at the Guild Lodge after docking there.
 * G.E.T. has done away with Arrivals Screen refuel/repair/enhancement summaries in favour of <u>more succinct console messages</u>, facilitating swifter passage to the Market. The Guilder is directed now to the <b>F4 Interfaces</b> for fuller data on recent ship enhancements under "<u>G.E.T. Ship Status Report</u>".
 * Various persistent - and perhaps annoying - ET behavioural glitches have been remedied.
 * At every system's witchpoint you will find a <b>Guild Lodge</b>. In keeping with G.E.T.'s arcane and esoteric Order, these are small <u>pyramidal</u> stations offering welcome, ceremonial, cameraderie, and a trading floor - but no shipyard. One of the Lodge's external faces sports Galcop insignia for obfuscatory purposes and to assure a small police presence. <u>Games may not be saved</u> from inside a Lodge. The Guild Lodge flashes green and orange on your scanner.
 * An ancient Guild tradition is the deployment of <b>three guardian ships</b>. Today, these are well-equipped Constrictor IIg models. A guardian will do nothing but patrol near the Lodge, unless disturbed. Guardians, in addition to the small (suborned) police presence which all Lodges attract, make a Guild Lodge's vicinity one of the safest - if not <i>the</i> safest - in the entire system. Guardian ships flash blue and orange on your scanner.
 * The Guild accounts as a <b>gift</b> the rescuing of any escape pod, be its occupant of the innocent or the guilty. Saving the helplessly adrift will gain a Guilder not only merit, but also, as befits a gift of this nature, a <b>5-point ship enhancement</b> plus a real <b>Gift to the Guild of 1000 credits</b> to further Grade advancement. This of course <u>on top of any bounty</u> that Galcop deems you worthy of.
 * "Cloaking technology" - that 'Galcop advance' much rumoured and whispered about - was, in fact, long ago an invention of the Guild. They called their device the <b>Hull Shroud</b>. Needless to say, you, as a Guilder, can have it - at a price. Seek it at Stations with a high technological index.
 * The <b>Constrictor II</b> - FE Shipyards' 'black project' - is no longer the restricted perk only of Grand Masters. You, as a lowly 'Master' will now find it available, if you look hard. And it's not at all expensive! [nominal specs: thrust = 26; speed = 350; pylons = 4; capacity = 80 TC. Please note: this <u>exclusive ET ship</u> is designed for parity with <b>FE Ships</b>, not vanilla Oolite ships.]
 * G.E.T. will pay to all Guilders except Grocers a regular and periodic <b>Bonus</b>. Guild bonuses are in gratitude for "service, devotion, and fortitude." Bonuses are time-, Grade-, and performance-dependant: <u>the higher you are in Grade</u> and the more <u>credits you have banked</u>, the higher will be your Bonus.
 * G.E.T. owns to a new <u>sensitivity</u> to their Guilders' <b>species-gender</b> - you can be addressed now as "Sister", "Brother", "Sibling" (bi-,&nbsp;tri-&nbsp;or null-sexed&nbsp;persons), or just 'Guilder' (the default).
 * As well as speedier Grade advancement, your <b>gifts</b> to the Guild bring with them <b>3-point ship enhancements</b>.
 * Practical <b>console advisories</b> onstation for Grocers who have not yet made 4&nbsp;runs.
 * G.E.T. begins to take account of <b>time</b>...
 * <b>Time spent as a Good Guilder</b> is recorded on your F5F5 Manifest in <u>Lave days</u> (and Lave years).
 * <b>System-to-System Runs</b> as a Good Guilder are numerically displayed on the F5F5 Manifest.
 * Main Station no longer mass-locks your ship on approach (so please take care you don't slam into it!) (Grade 1 and above)

   Version 1.18
   ------------
 * In spite of the addition of the new F4 page 'Gift to Guild' (which speeds advancement in Grade), progression to the Elevated and Exalted Grades (10-22) has been made more arduous.
 * Donations are no longer limited to one per system: they are cumulative within the system.
 * "Buber's Beats" Milk Run guide for inductees on the F4 Interfaces screen.
 * 'Milk or Cream? - Buber's Beats' - a comprehensive wiki section with solid guidance, a truncated version of which appears in-game.
 * Owing to a ballooning volume of Guild applications (blame TM!), the 'black box' anti-Masslock device is now reserved for Probationary Grade 1 and above.
 * Buying and selling from and to multiple stations insystem is facilitated.
 * More data now appears on the G.E.T. F5 Mission screen.
 * Gifts and Last trade (with star, station, and goods) added to F5 Mission screen.
 * Since space allows it, a station's secondary legal commodity is now listed by the F4 Master Advisory along with the primary.
 * Much revision of the F4 Interfaces texts.
 * More immersive comms messages geared to Grocers.
 * Witchpoint Trade Advisory messages made more succinct.
 * A slight re-ordering and renaming of the G.E.T. Grades.
		
 (Please see https://wiki.alioth.net/index.php/Elite_Trader_OXZ)
		 
*/

	
this.playerSoldCargo = function(commodity, units, price) {
	var sale = 0, tp = "", tm = "", c=commodity,
	prec = ((c=="gold")||(c=="platinum")||(c=="gem_stones"));
	// Guild sales are conditional upon...
	var cond = ((this.$etLastPrice[c]>0) && (!prec));
	// selling preliminaries - update quantity and price
	if (cond) {
		sale = price * units;
		// this sale's profit & total profit
		this.$etProfit = sale - this.$etLastBuy[c];
		// note the commodities sold
		if (this.$etProfit>0) this.$etCommodities += c + " ";
		// allow for multiple station trades insystem (TEST!)
		//this.$etLastProfit = this.$etTotProfit;
		this.$etTotProfit += this.$etProfit;
		// allow for multiple station trades insystem (TEST!)
		this.$etLastProfit = this.$etTotProfit;
		// prepare trade messages
		tp="   ( "+formatCredits(this.$etTotProfit/10,true,true)+" )";
		tm="Trade ("+c+"): "+formatCredits(this.$etProfit/10,true,true);
		/* max trade is calculated outside Market screen */
	}
	// see if we made a profit 
	this.$etMadeProfit = ((this.$etProfit>0) && (cond));

	// conditions for scoring
	this.$etOKtoScore = ((units > 2) && (!this.$etDone) && (this.$etBoughtUnits>0) && (this.$etMadeProfit) && (!this.$etIsBellig) && (!this.$etBeenBellig) && (!this.$etIsScooper));
	
	// decrement the manifest by # of units and price
	if (cond) {
		this.$etBoughtUnits -= units;
		this.$etBoughtPrice -= this.$etLastPrice[c] * units;
	}
	// display ship's cargo and its purchase value
	if ((price==this.$etLastPrice[c]) && (!prec)) this._etPodsInHold(this.$etBoughtUnits);	

	var pm = player.consoleMessage;
	// credit a "market killing" on first profitable sell
	if (this.$etOKtoScore) {
		player.score++;
		this.$etPoints++;
		this.$etHasScored = true;
		pm("You made a killing!"+tp);
		if (!this.$etMarketObserver) pm(tm);
		// for simplicity, only one score per station
		this.$etDone = true;
	// otherwise acknowledge a skillful trade if we're not just unloading
	} else if (this.$etMadeProfit && (price!=this.$etLastPrice[c]) && (this.$etStation!=this.$etLastStation)) {
		pm("Nice trade!"+tp);
		if (!this.$etMarketObserver) pm(tm);
	}
}
	

this.playerBoughtCargo = function (commodity, units, price) {
	var c=commodity,
	prec = ((c=="gold")||(c=="platinum")||(c=="gem_stones"));
	// buying preliminaries - record quantity and price
	if (!prec) {
		this.$etBoughtUnits += units;
		this.$etBoughtPrice += price * units;
		this.$etLastBuy[c] = price * units;
		this.$etLastPrice[c] = price;
		// display ship's cargo and its purchase value
		this._etPodsInHold(this.$etBoughtUnits);
	}
}


this.guiScreenChanged = function(to, from) {
	var pm = player.consoleMessage;
	// update G.E.T. Status on Manifest screen
	if (from == "GUI_SCREEN_MARKET") {
		// record last profit - for multiple station trades (TEST!)
		this.$etLastProfit=this.$etTotProfit;
		this._etGetMaxTrade();
		// deduct donation from player's credits
		if (this.$etProfit>0) {
			this.$etDonation = this._etGetDonation(this.$etTotProfit);
			if (this.$etDonation>0) {
				this.$etDonations += this.$etDonation;
				// donation is decicredits, so convert
				player.credits -= this.$etDonation/10; 
				pm("Your gift is accepted with appreciation.",5);
				pm("Advancement is secure!",5);
			}
		}
		// include donation in status report
		this._etShowStatus();
	} else
	if (to == "GUI_SCREEN_MARKET") {
		// reset local individual profit
		if (!this.$etCheat) this.$etProfit=0;
		// a G.E.T. presence on the market floor
		pm("The "+this.$etSystem+" Guild of Elite Traders", 5);
		// show hold-status on entering Market
		var pods = this._etPodCount();
		this._etPodsInHold(pods);
		// advise player to unload and re-buy cargo after game-load w/ full hold
		if ((pods>0) && (this.$etBoughtPrice<=0)) pm("Elite Trader: Please sell cargo and re-buy.",5); 
	} else
	if (to == "GUI_SCREEN_MANIFEST") {
		// show best trade status on Manifest screen
		this._etShowStatus();
		// G.E.T. presence on the Manifest screen
		pm("Under the aegis of the "+this.$etSystem+" G.E.T", 10);
	} else 
	if (to == "GUI_SCREEN_STATUS")
		if (!this.$etVowing) {
			if (this.$etIsWelcomed) {
				if (!this.$etMadeProfit)
					pm("We trust your stay at "+this.$etSystem+" proves profitable!", 10);
				else pm(this.$etSystem+" is your lucky star!", 10);
			} else {
				// Welcome only said here!
				if (!this.$etIsWelcomed) this._etSayWelcome();
			} 
		} else this.$etVowing = false;
}


this.shipDockedWithStation = function(station) {
	this.$etLastStation = this.$etStation;
	this.$etStation = station;
	this.$etLastSystem = this.$etSystem;
	// clear flags and sold-quantities on docking
	this.$etDone = false;
	this.$etMadeProfit = false;
	this.$etHasScored = false;
	this.$etProfit = 0;
	// total profit is reset at WP exit
	this.$etCommodities = "";
	// leave an identical ship at the shipyard
	// in case player wishes to reset its specs
	this._etCloneShip();
	var stan = player.ship.dockedStation.name;
	if (!this.$etBeenBellig) {
		// prep G.E.T. Advsory interface
		this._etPrepAdvisory(station);
		// prep G.E.T. Max Trade Resetter
		this._etPrepResetter(station);
		// prep G.E.T. Ship Status Report
		this._etPrepShipStatus(station);
		// prep G.E.T. Gift to Guild
		this._etPrepGift(station);
		// prep walkthrough
		this._etPrepBeats (station);
		// if at a Lodge, prep Sales Advisory
		if (stan=="G.E.T. Guild Lodge")
			this._etPrepSales(station);
		// prep gender if not yet known
		if (!this.$etGendered)
			this._etPrepGender(station);
	} else this._etPrepVow(station);
	// generate G.E.T. contact name (Assessor)
	this.$etContact = randomName() + " " + randomName();
	// calculate monthly bonus (if any)
	var mb = this._etGetMBonus();
	var dy = this._etGetDays();
	var ld = this.$etLastBonusDay;
	if ((mb > 0) && (ld != dy)) {
		player.credits += mb;
		this.$etBonuses += mb;
		this.$etBonusCount ++;
		// prevent double bonus
		this.$etLastBonusDay = dy; 
	}
	// At least one Constrictor II customer model
	if (system.techLevel>=10) this._etAddShip("FE_constrictor2-player", "Constrictor II", 143000);
}


this.shipWillDockWithStation = function(station) {
	var pc = player.consoleMessage;
	// Boon for docking with a Guild Lodge
	if (station.name == "G.E.T. Guild Lodge") { 
		if (!this.$etBooned) {
			player.credits+=100.0;
			pc(this.$etBro+", your Guild Boon has been given.");
			this.$etBooned = true;
		}
	}
	var p=player.ship;
	if ((!this.$etIsBellig) && (!this.$etBeenBellig)) {
		// refuel a good Guilder's ship
		p.fuel = 7;
		// repair a good Guilder's ship
		p.serviceLevel = 100;
		pc("Ship refuelled and repaired...",9);
		// if the Brother's recent trades were satisfactory...
		if (this.$etHasScored) { 
			// incremental enhancements for the Guilder's ship
			this._etEnhanceShip(1);
			// report refuel, repair, and enhancement
			pc("Ship enhancements +1 - see F4 Interfaces.",9);
			pc(" ");
		}
	}
	// remove fast-docking equipment
	p.removeEquipment("EQ_ET_AUTODOCK");
	// reset station profit
	this.$etLastProfit=0;
}


this.shipWillLaunchFromStation = function(station) {
	// G.E.T. ensures the good Brother's record is always clean
	if ((!this.$etIsBellig) && (!this.$etBeenBellig)) {
		player.ship.bounty = 0;
		// enable fast docking
		this._installAutoDock();
	}
	this.$etIsWelcomed = false;
}


this.shipLaunchedFromStation = function(stationLaunchedFrom) {
	if (!this.$etBeenBellig)
		player.commsMessage("The "+this.$etSystem+" G.E.T. Aegis wishes you clear lanes and a quiet passage. Return safe!", 6);
	// weapons offline is the G.E.T. approved setting
	//player.ship.weaponsOnline = false; // doesn't appear to be writable
}


this.playerStartedJumpCountdown = function(type, seconds) {
	if (!this.$etBeenBellig)
		player.commsMessage("Be careful out among the miscreants "+this.$etBro+"!",6);
	if ((!this.$etIsBellig) && (!this.$etBeenBellig) && (!this.$etIsScooper) && (!player.ship.weaponsOnline)) player.ship.massLockable = this._etStrict();
}


this.shipEnteredStationAegis = function(station) {
	if (!this.$etBeenBellig)
		player.commsMessage("The Galactic Guild of Elite Traders welcomes you to "+this.$etSystem+" Aegis! We are at your disposal in the shipyard. Trade well!", 6);
	player.ship.massLockable = this._etStrict(); // true: no slamming into station
}


this.weaponsSystemsToggled = function(state) {
	// Strict mode for Grade 0, or not...
	if (this._etStrict()) {
		player.ship.massLockable = true;
		player.commsMessage(this.$etBro+", Grade 1 must be attained...",9);
		player.commsMessage("Please take care off-lane.",9);
	} else {
		// weapons online enables mass-locking
		player.ship.massLockable = state;
		if (state) var s="OFF"; else var s="ON";
		player.commsMessage("Anti-masslock system "+s);
	}
}


this.shipKilledOther = function(whom, damageType) {
	 // discount tins of SPAM and rocks
	 if ((whom.name!="SPAM") && (whom.name!="Asteroid")) {
		pm = player.commsMessage;
		// G.E.T. disapproval
		pm(this.$etSystem+" G.E.T. notes their Brother's lapse...");
		this.$etKillCount++;
		this.$etIsBellig = (this.$etKillCount>0); // temporary
		// a single kill might be accidental, but 3? - unlikely!
		if (this.$etKillCount>2) { 
			this.$etBeenBellig = true; // permanent - a blot on the record
			this._etFloorSpecs(); // ship specs back to nominal
			// refund donations
			player.credits += this.$etDonations/10;
			// and reset them
			this.$etDonations = 0.0;
			pm("Your gifts to the Guild have been returned.");
			pm("All G.E.T. privileges are rescinded.");
			pm("Vow to be a better Brother!");
		}
	}
}


this.shipScoopedOther = function(whom) {
     // G.E.T. disapproval
	player.commsMessage(this.$etSystem+" G.E.T. notes their Brother's lapse...");
	this.$etIsScooper = true;
}


this.playerRescuedEscapePod = function(fee, reason, occupant) {
    pc=player.commsMessage;
	// G.E.T. accounts the saving of any miscreant a _gift_
	// the Guilder's selfless act does not go unrewarded
	player.credits += 1000.0;
	this._etEnhanceShip(5);
	pc(this.$etBro+", we account your saving of this miscreant a *gift*...",9);
	pc("Your selfless and noble act has not gone unrewarded!",9);
}


this.shipEnteredPlanetaryVicinity = function(planet) {
	player.commsMessage("Entering gravity of "+this._etGetPlanetName(planet));
	// Weps will always masslock near planets
	if (player.ship.weaponsOnline) player.ship.massLockable = this._etStrict(); // no slamming into planet
}


this.shipExitedPlanetaryVicinity = function(planet) {
	player.commsMessage("Leaving gravity of "+this._etGetPlanetName(planet));
	if ((!this.$etIsBellig) && (!this.$etBeenBellig) && (!this.$etIsScooper) && (!player.ship.weaponsOnline)) player.ship.massLockable = this._etStrict();
}


this.shipExitedWitchspace = function() {
	// add Guild Lodge and 3 Guardians
	var adds = system.legacy_addShipsWithinRadius;
	adds("lodge", 1, "wpu", [0, 0, 0], 6400);
	adds("guardian", 3, "wpu", [0, 0, 0], 6400);
	// reset globals that require it
	this.$etSystem = System.systemNameForID(system.ID);
	this.$etIsWelcomed = false;
	if (this.$etKillCount>0) this.$etKillCount--;
	this.$etIsBellig = (this.$etKillCount>0);
	this.$etIsScooper = false;
	// total profit is for system
	this.$etTotProfit = 0;
	// (reset) for multiple station trades
	this.$etLastProfit = 0;
	this._etGetMaxTrade();
	// one donation and gift per system
	this.$etDonated = false;
	this.$etGifted = false;
	// no-skip in Grade check (reset for system)
	this.$etLastGrade = 0;
	// build G.E.T. status screen
	this._etShowStatus();
	// witchpoint fuelling for GBs past probation
	var p=player.ship, pc=player.commsMessage;
	if ((!this.$etIsBellig) && (!this.$etBeenBellig) 
		&& (!p.weaponsOnline) && (this._etGetGrade()>1)) {
		p.fuel = 7;
		pc(""); // LF
		pc("Witchpoint fuelling complete.");
		pc(this.$etSystem+" G.E.T. wishes their "+this.$etBro+" a peaceful jump.");
		// witchpoint Trade Advisory (where to sell)
		this._etCommsTradeAdvisory();
	}
	// advice for Grocers
	if (this._etStrict()) pc(this.$etBro+" Grocer, go off-lane... be safe!");
	// increment number of sys-to-sys runs
	this.$etRuns+=1;
	// Guild Boon once per system
	this.$etBooned = false;
	// report miscreants in system
	var mis = system.countShipsWithPrimaryRole("pirate");
	pc(" ");
	pc("Miscreants in system: "+mis,9);
	pc(" ");
}


this.playerBoughtNewShip = function(ship, price) {
	// spec globals to ship's initial values
	this._etResetSpecs();
	this.$etShipChanged = true;
	this._etGetMaxTrade();
	this._etShowStatus();
}


this.playerWillSaveGame = function(message) {
	missionVariables.etSpeed = this.$etLastSpeed; 
	missionVariables.etThrust = this.$etLastThrust;
	missionVariables.etEnergy = this.$etLastEnergy;
	missionVariables.etShields = this.$etLastShields;
	missionVariables.etRecharge = this.$etLastRecharge;
	missionVariables.etERecharge = this.$etLastERecharge;
	missionVariables.etPoints = this.$etPoints;
	missionVariables.etKills = this.$etKillCount;
	missionVariables.etMaxTrade = this.$etMaxTrade;
	missionVariables.etMinTrade = this.$etMinTrade;
	missionVariables.etMaxTSystem = this.$etMaxTSystem;
	missionVariables.etMaxTGoods = this.$etMaxTGoods;
	missionVariables.etMaxTShip = this.$etMaxTShip;
	missionVariables.etMaxTShipName = this.$etMaxTShipName;
	missionVariables.etMaxTShipTC = this.$etMaxTShipTC;
	missionVariables.etVowCount = this.$etVowCount;
	missionVariables.etDonations = this.$etDonations;
	missionVariables.etGifts = this.$etGifts;
	missionVariables.etGiftCount = this.$etGiftCount;
	missionVariables.etGendered = this.$etGendered;
	missionVariables.etBro = this.$etBro; // gender!
	missionVariables.etRuns = this.$etRuns;
	missionVariables.etYears = this.$etYears;
	missionVariables.etDays = this.$etDays;
	missionVariables.etDaysStart = this.$etDaysStart; // set only once in script!
	missionVariables.etBonuses = this.$etBonuses;
	missionVariables.etBonusCount = this.$etBonusCount;
	missionVariables.etLastBonusDay= this.$etLastBonusDay;
	missionVariables.etNoob= this.$etNoob;
	// cannot save booleans as "false/true" - must convert
	// set only once at Guilder career start
	if (this.$etDaysStarted) var dstd=1; else var dstd=0;
	missionVariables.etDaysStarted = dstd;
	// cannot save booleans as "false/true" - must convert
	if (this.$etGendered) var gen=1; else var gen=0;
	missionVariables.etGendered = gen;
	// cannot save booleans as "false/true" - must convert
	if (this.$etStrict) var strct=1; else var strct=0;
	missionVariables.etStrict = strct;
	// cannot save booleans as "false/true" - must convert
	if (this.$etBeenBellig) var bb=1; else var bb=0;
	missionVariables.etBeenBellig = bb;
}


this.startUpComplete = function () {
	var p = player.ship;
	this.$etSystem = System.systemNameForID(system.ID);
	this._etResetSpecs();
	// default is current ship
	this.$etMaxTShip = p.shipClassName;
	this.$etMaxTShipName = p.shipUniqueName;
	this.$etMaxTShipTC = p.cargoSpaceCapacity;
	// Load saved globals, if present
	var spd = missionVariables.etSpeed;
	var thr = missionVariables.etThrust;
	var ene = missionVariables.etEnergy;
	var shi = missionVariables.etShields;
	var rec = missionVariables.etRecharge;
	var rece = missionVariables.etERecharge;
	
	if (spd>=this.$etInitialSpeed) this.$etLastSpeed = spd;
	if (thr>=this.$etInitialThrust) this.$etLastThrust = thr;
	if (ene>=this.$etInitialEnergy) this.$etLastEnergy = ene;
	if (shi>=this.$etInitialShields) this.$etLastShields = shi;
	if (rec>=this.$etInitialRecharge) this.$etLastRecharge = rec;
	if (rece>=this.$etInitialERecharge) this.$etLastERecharge = rece;
	
	if (spd>=this.$etInitialSpeed) p.maxSpeed = spd;
	if (thr>=this.$etInitialThrust) p.maxThrust = thr;
	if (ene>=this.$etInitialEnergy) p.maxEnergy = ene;
	if (shi>=this.$etInitialShields) p.maxForwardShield = shi;
	if (rec>=this.$etInitialRecharge) p.forwardShieldRechargeRate = rec;
	if (rece>=this.$etInitialERecharge) p.energyRechargeRate = rece;
	// load points here too
	var pts = missionVariables.etPoints; if (pts>0) this.$etPoints = pts;
	var kil = missionVariables.etKills; if (kil>0) this.$etKillCount = kil; 
	var maxt = missionVariables.etMaxTrade; this.$etMaxTrade = maxt;
	var mint = missionVariables.etMinTrade; this.$etMinTrade = mint;
	var maxts = missionVariables.etMaxTSystem; this.$etMaxTSystem = maxts;
	var maxtg = missionVariables.etMaxTGoods; this.$etMaxTGoods = maxtg;
	var maxts = missionVariables.etMaxTShip; if (maxts!="") this.$etMaxTShip = maxts;
	var maxtn = missionVariables.etMaxTShipName; if (maxtn!="") this.$etMaxTShipName = maxtn;
	var maxtt = missionVariables.etMaxTShipTC; if (maxtt!=0) this.$etMaxTShipTC = maxtt;
	var vc = missionVariables.etVowCount; if (vc!=null) this.$etVowCount = vc;
	var dons = missionVariables.etDonations; if (dons!=null) this.$etDonations = dons;
	var gifts = missionVariables.etGifts; if (gifts!=null) this.$etGifts = gifts;
	var gcount = missionVariables.etGiftCount; if (gcount!=null) this.$etGiftCount=gcount;
	var bro = missionVariables.etBro; if (bro!=null) this.$etBro = bro;
	var runs = missionVariables.etRuns; if (runs!=null) this.$etRuns = runs;
	var yrs = missionVariables.etYears; if (yrs!=null) this.$etYears = yrs;
	var days = missionVariables.etDays; if (days!=null) this.$etDays = days;
	var dayst = missionVariables.etDaysStart; if (dayst!=null) this.$etDaysStart = dayst;
	var bons = missionVariables.etBonuses; if (bons!=null) this.$etBonuses = bons;
	var bc = missionVariables.etBonusCount; if (bc!=null) this.$etBonusCount = bc;
	var lbd = missionVariables.etLastBonusDay; if (lbd!=null) this.$etLastBonusDay = lbd;
	var noo = missionVariables.etNoob; if (noo!=null) this.$etNoob = noo;
	// have we started the clock? - permanent and persistent
	if (missionVariables.etDaysStarted != null) {
		var dstd=missionVariables.etDaysStarted;
		this.$etDaysStarted = (dstd == 1);
	}
	// cannot load booleans as "true/false" - must convert
	if (missionVariables.etBeenBellig != null) {
		var bb=missionVariables.etBeenBellig;
		this.$etBeenBellig = (bb == 1);
		// floor ship specs if the Brother went bad
		if (this.$etBeenBellig) this._etFloorSpecs();
	}
	// waive or allow Grade 0 strictures
	if (missionVariables.etStrict != null) {
		var strct=missionVariables.etStrict;
		this.$etStrict = (strct == 1);
	}
	// Gender-check (persistent)
	if (missionVariables.etGendered != null) {
		var gen=missionVariables.etGendered;
		this.$etGendered = (gen == 1);
	}
	// loading globals complete.
	if (this._etHasFE()) log(this.name, "finds FE Ships present ("+p.shipClassName+")");
	// dock ship
	var sta = p.dockedStation;
	this.shipDockedWithStation(sta);
	// welcome revenant back to station
	var pc = player.consoleMessage, s=this.$etSystem;
	if (this.$etRuns>0) pc("Delighted to have you back at "+s+", "+this.$etBro+"!",9);
	this._etGetMaxTrade();
	this._etShowStatus();
	var stan = player.ship.dockedStation.name;
	if (!this.$etBeenBellig) {
		// prep G.E.T. Advisory interface
		this._etPrepAdvisory(sta);
		// prep G.E.T. Max Trade Resetter
		this._etPrepResetter(sta);
		// prep G.E.T. Ship Status Report
		this._etPrepShipStatus(sta);
		// prep Gift solicitation
		this._etPrepGift (sta);
		// prep walkthrough
		this._etPrepBeats (sta);
		// if at a Guild Lodge, prep Sales Advisory
		if (stan=="G.E.T. Guild Lodge")
			this._etPrepSales(sta);
		// conditionally, prep gender request
		if (!this.$etGendered) this._etPrepGender(sta);
	} else this._etPrepVow(sta);
	// set Grade Advance divisor according to present Grade
	var grade=this._etGetGrade();
	this._etSetGradeAdvance(grade);
	// determine strictness (anti-masslock on or off)
	this.$etStrict = this._etStrict();
	// start the career clock if not already started
	if (!this.$etDaysStarted) { 
		this.$etDaysStart = clock.days;
		this.$etDaysStarted = true;
	}
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// declare & initialize globals
	this.$etMarketObserver = false;
	if (worldScripts["market_observer3"]) 
		this.$etMarketObserver = true;
	this.$etNoob = "yes";
	this.$etIsWelcomed = false;
	this.$etDone = false;
	this.$etMadeProfit = false;
	this.$etOKtoScore = false;
	this.$etHasScored = false;
	this.$etIsWelcomed = false;
	this.$etShipChanged = false;
	this.$etIsScooper = false;
	this.$etIsBellig = false; // temporary
	this.$etBeenBellig = false; // permanent
	this.$etDonated = false;
	this.$etGifted = false;
	this.$etKillCount = 0; // ship-kills
	this.$etPoints = 0; // G.E.T. Elite-points scored
	this.$etVowCount = 0;
	this.$etVowing = false; // controls post-vow message
	this.$etBoughtPrice = 0;
	this.$etBoughtUnits = 0;
	this.$etProfit = 0;
	this.$etTotProfit = 0;
	this.$etLastProfit = 0; // for multiple station trades insystem
	this.$etMaxTrade = 0;
	this.$etMinTrade = 1000000;
	this.$etDonation = 0.0; // donation on station profit
	this.$etDonations = 0.0; // total 'donations' to G.E.T.
	this.$etGift = 0.0; // 'gift' (voluntary) of station profit
	this.$etGifts = 0.0; // total 'gifts' to Guild coffers
	this.$etGiftCount= 0; // how many gifts we've given
	this.$etStrict=true; // waive or allow Grade 0 stricture
	this.$etLastGrade=0; // for Grade no-skip check
	this.$etSystem = "";
	this.$etLastSystem = "";
	this.$etNextSystem = "";
	this.$etContact = ""; // named station contact (Assessor)
	this.$etCommodities = ""; // commodities sold
	this.$etMaxTSystem = ""; // best trade's systen
	this.$etMaxTGoods = ""; // best trade's commodity
	this.$etMaxTShip = ""; // best trade's ship class
	this.$etMaxTShipName = ""; // best trade's ship name
	this.$etMaxTShipTC = 0; // best trade's ship tonnage
	this.$etStation = new Object(); // ??
	this.$etLastStation = new Object(); // ??
	this.$etLastPrice = new Array();
	for (var c=0; c<20; c++) this.$etLastPrice[c]=0;
	this.$etLastBuy = new Array();
	for (c=0; c<20; c++) this.$etLastBuy[c]=0;
	
	this.$etInitialSpeed = 0;
	this.$etInitialThrust = 0;
	this.$etInitialEnergy = 0;
	this.$etInitialShields = 0;
	this.$etInitialRecharge = 0.0; // shields recharge
	this.$etInitialERecharge = 0.0; // energy recharge

	this.$etLastSpeed = 0.0; 
	this.$etLastThrust = 0;
	this.$etLastEnergy = 0;
	this.$etLastShields = 0;
	this.$etLastRecharge = 0.0;
	this.$etLastERecharge = 0.0;
	
	// constants
	this.$etLimitSpeed = 512;
	this.$etLimitThrust = 256;
	this.$etLimitEnergy = 1024;
	this.$etLimitShields = 512;
	this.$etLimitRecharge = 16.0; // shield-R should be half energy-R
	this.$etLimitERecharge = 32.0; 
	
	this.$etGradeAdvance = 100000; // default 100000 (10,000 cr)
	
	// G.E.T. Grade Titles
	this.$etGETTitle = [
	"Grocer",
	"Entered Apprentice",
	"Fellowcrafter",
	"Master Trader",
	"Master Traveller",
	"Perfect Master",
	"Master of the Brazen Serpent",
	"Provost and Judge",
	"Intendant of the Orbital",
	"Master of the Guild House",
	"Master Elect",
	"Sublime Master Elected",
	"Master of Mercy", 
	"Master of the Ninth Arch",
	"Grand Elect Master",
	"Knight of the East",
	"Knight of the East and West",
	"Knight of the Rosy Star",
	"Friend and Brother Eternal",
	"Prince of Inera",
	"Sublime Keeper of the Galactic Secret", 
	"Grand Master Supreme, Serene and Sublime",
	"Elite Grand Master Everlasting"
	];
	// Roman numerals for planet nomenclature
	this.$etRoman = ["","I","II","III","IV","V","VI","VII","VIII","IX","X"];
	// Industrial and Agricultural products
	this.$etIGoods = ["computers","firearms","machinery","luxuries","alloys"];
	this.$etAGoods = ["furs","liquor_wines","radioactives","slaves","minerals","textiles","food"];
	this.$etCheat = false; // toggle 'hidden feature' for testing - default OFF
	// Brother or Sister?
	this.$etBro = "Guilder"; // switchable to "Sister", "Brother", or "Sibling"
	this.$etGendered = false; // true once imparted
	// number of system-to-system runs
	this.$etRuns = 0;
	// number of years as a Guilder
	this.$etYears = 0.0; // years passed since induction
	// constant: days in Lave Year - can (should?) be adjusted up/down
	this.$etLaveYear = 365;
	// days as a Guilder
	this.$etDays = 0; // days passed since G.E.T. induction
	this.$etDaysStart = 2084004; // day(s) _at_ G.E.T. induction
	this.$etDaysStarted = false; // have we started the G.E.T. clock?
	// total time or runs bonuses paid by G.E.T.
	this.$etBonuses = 0.0;
	this.$etBonusCount = 0;
	this.$etLastBonusDay = 0;
	// Guild Boon paid once per system
	this.$etBooned = false;
}


// are we being strict? (grade-dependent)
this._etStrict = function() {
	var strict = (this._etGetGrade() < 1);
	this.$etStrict = strict;
	return strict;
}


// obtain the G.E.T. numeric grade (from total donation)
this._etGetGrade = function() {
	var grade = 0;
	var lim=this.$etGETTitle.length-1;
	var don = this.$etDonations.toFixed(0); // use parseInt()?
	// set Grade Advance according to present grade
	grade = (don/this.$etGradeAdvance);
	grade = grade.toFixed(0); // use parseInt()?
	if (grade>lim) grade=lim;
	return grade;
}


// set grade advance divisor according to present Grade
this._etSetGradeAdvance = function() {
	var grade = this._etGetGrade();
	if (grade<6)  this.$etGradeAdvance = 100000; else
	if (grade<13) this.$etGradeAdvance = 150000; else
	if (grade<18) this.$etGradeAdvance = 200000; else
	if (grade<20) this.$etGradeAdvance = 300000; else
	if (grade<23) this.$etGradeAdvance = 400000; 
}


// # of cargo pods in ship's hold
this._etPodCount = function() {
	var result = 0, man=manifest.list;
	for (var i=0; i<man.length; i++) {
		var q = man[i].quantity;
		if (q > 0) result+= q;
	}	
	return result;
}


// is FE Ships Player installed?
this._etHasFE = function() {
	var str = player.ship.shipClassName;
	var n = str.search(" FE");
	return (n>-1);
}


// leave an identical ship at the shipyard
// in case player wishes to reset its specs
this._etCloneShip = function() {
	if (oolite.versionString>"1.88") {
		var pr = player.ship.price * 0.75;
		system.mainStation.addShipToShipyard({ 
			short_description: "G.E.T. offers you this clone of your ship, to reset our augmented specs to nominal, should you desire a clean break.", 
			shipdata_key: player.ship.dataKey, 
			price: pr, 
			personality:0,
			extras:[""]
		});
	}
}


// Brother's profit-donation to G.E.T
// * in decicredits *
this._etGetDonation = function(profit) {
	var donation = 0.0;
	if (!this.$etDonated) {
		if (profit>100.0) // > 10.0 cr
			// profit > 100 cr = 1% donation
			if (profit<=10000.0) { // <= 1000.0 cr
			donation = profit * 0.01;
			// proft > 1000 cr = 10% donation
			} else donation = profit * 0.1;
	}
	return donation;
}


// Brother's running max/min trades and commodities
this._etGetMaxTrade = function() {
	if (this.$etTotProfit>this.$etMaxTrade) {
		this.$etMaxTrade=this.$etTotProfit;
		this.$etMaxTSystem=this.$etSystem;		
		this.$etMaxTGoods=this.$etCommodities;		
		// the ship we maxed it in
		var p = player.ship;
		this.$etMaxTShip = p.shipClassName;
		this.$etMaxTShipName = p.shipUniqueName;
		this.$etMaxTShipTC = p.cargoSpaceCapacity;
	}
	if (this.$etTotProfit<this.$etMinTrade) this.$etMinTrade=this.$etTotProfit;
}


// Brother's standing, best trade, today's profit, donations etc --> Manifest
this._etShowStatus = function() { 
	if (this.$etBeenBellig) var br = "Bad"; else
	if (this.$etIsBellig) var br = "Errant"; else
	if (this.$etVowCount>0) var br = "Reformed"; else
		var br = "Good"; 
		var bro = this.$etBro; // gender!
	var pn = player.name;
	var statusBrother = br+" "+bro+" "+pn+", with "+formatCredits(player.credits, true, true);
	// days or years as a Guilder
	var dg = this._etGetDays(); // this.$etDays-this.$etDaysStart; 
	var yg=this._etGetYears();
	var statusTime = "Time as a "+bro+": "+dg+" Lave days ("+yg+" LY)";
	// number of runs as a Guilder
	var runs=player.score;
	if (this.$etRuns<=0) runs = player.score; 
		else runs=this.$etRuns; // (best guess or # of runs)  
	this.$etRuns = runs; // set here each time - belt'n'braces
	var statusRuns = "System-to-System Runs: "+runs; //this.$etRuns;
	// most profitable trade so far
	var statusTrade = "Best trade: " + formatCredits(this.$etMaxTrade/10, true, true ) + " (" + this.$etMaxTSystem + " - "+this.$etMaxTGoods+")";
	// ship + tonnage in which best trade was made
	var sn = this.$etMaxTShipName; 
	if ((sn=="") || (sn==null)) sn = ""; else sn=" '"+this.$etMaxTShipName+"'"; 
	var statusShip = "Ship: "+this.$etMaxTShip+sn+" ("+this.$etMaxTShipTC+" TC)";
	// present orbital (station)
	var ps=player.ship, po="none";
	if (ps.dockedStation!=null) po=ps.dockedStation.displayName; 
	var statusOrb = "Orbit: " + this.$etSystem +" "+po; 
	// last market trade
	var lp = this.$etLastProfit/10;
	var statusLastt = "Last trade: "+formatCredits(lp,true,true)+" ("+this.$etSystem+" "+po+" - "+this.$etCommodities+")";
	// total profit this system (so far)
	// allow for multiple market & station trades insystem
	// (may not be the best method, but the simplest)
	if (this.$etLastProfit != this.$etTotProfit) this.$etTotProfit += this.$etLastProfit;
	var tp = this.$etTotProfit/10;
	var profitTotal = "Profit here: "+formatCredits(tp,true,true);
	// (monthly) time bonuses paid by G.E.T. to Guilder
	var mb = this.$etBonuses; var mbc = this.$etBonusCount;
	var statusBonus = "Bonuses: " + formatCredits(mb,true,true) + " ("+ mbc + ")";
	// donation this station
	var don = this.$etDonation/10; 
	var statusDonation = "Donation here: "+formatCredits(don,true,true);
	// total donations as cr
	var dons = this.$etDonations/10;
	var statusDonations = "Donations & Gifts: "+formatCredits(dons,true,true);
	// Gifts
	var gifts = this.$etGifts/10; 
	var gc=this.$etGiftCount;
	var statusGifts = "Gifts: "+formatCredits(gifts,true,true)+" ("+gc+")";
	// G.E.T. Grade and Title
	// set Grade Advance divisor according to present Grade
	this._etSetGradeAdvance();
	var grade = this._etGetGrade();
	var statusGrade = "Grade "+grade;
	var title = this.$etGETTitle[grade];
	statusGrade += ": "+title;
	// display the G.E.T. Status Report
	mission.setInstructions(["G.E.T. Status:",statusBrother,statusTime,statusRuns,statusOrb,statusTrade,statusShip,statusLastt,profitTotal,statusBonus,statusDonation,statusDonations,statusGifts,statusGrade], this.name);
}


// add a specified ship to Main shipyard
this._etAddShip = function(id,name,pr) { 
	system.mainStation.addShipToShipyard({ 
		short_description: name+": standard customer model, price "+formatCredits(pr,true,true)+".", 
		shipdata_key: id, 
		price: pr, 
		personality:0,
		extras:[""]
	});
}


// enhance ship by <points> points
this._etEnhanceShip = function(points) {
	var p = player.ship;
	// incremental defensive enhancements for the Guilder's ship
	if (this.$etLastSpeed<this.$etLimitSpeed) {
		// secure against possible O-drive corruption
		p.maxSpeed=this.$etLastSpeed+1.0;
		}
		if (this.$etLastThrust<this.$etLimitThrust) {
			p.maxThrust+=points;
		}
		if (this.$etLastShields<this.$etLimitShields) {
			p.maxForwardShield+=points;
			p.maxAftShield+=points;
		}
		if (this.$etLastEnergy<this.$etLimitEnergy) {
			p.maxEnergy+=points;
		}
		if (this.$etLastRecharge<this.$etLimitRecharge) {
			p.forwardShieldRechargeRate+=(points*0.05);
			p.aftShieldRechargeRate+=(points*0.05);
		}
		if (this.$etLastERecharge<this.$etLimitERecharge) {
			p.energyRechargeRate+=(points*0.1);
		}
		// update last specs after increments
		this.$etLastSpeed=p.maxSpeed; 
		this.$etLastThrust=p.maxThrust;
		this.$etLastShields=p.maxForwardShield;
		this.$etLastEnergy=p.maxEnergy;
		this.$etLastRecharge=p.forwardShieldRechargeRate;
		this.$etLastERecharge=p.energyRechargeRate;
}


// nullify ship enhancements, setting specs to nominal
this._etFloorSpecs = function() {
	var p = player.ship;
	this.$etLastSpeed = this.$etInitialSpeed; 
	this.$etLastThrust = this.$etInitialThrust;
	this.$etLastShields = this.$etInitialShields;
	this.$etLastEnergy = this.$etInitialEnergy;
	this.$etLastRecharge = this.$etInitialRecharge;
	this.$etLastERecharge = this.$etInitialERecharge;

	p.maxSpeed = this.$etInitialSpeed;
	p.maxThrust = this.$etInitialThrust;
	p.maxForwardShield = this.$etInitialShields;
	p.maxAftShield = this.$etInitialShields;
	p.maxEnergy = this.$etInitialEnergy;
	p.forwardShieldRechargeRate = this.$etInitialRecharge;
	p.aftShieldRechargeRate = this.$etInitialRecharge;
	p.energyRechargeRate = this.$etInitialERecharge;
}


this._etResetSpecs = function() {
	var p = player.ship;
	this.$etLastSpeed = p.maxSpeed; 
	this.$etLastThrust = p.maxThrust;
	this.$etLastShields = p.maxForwardShield;
	this.$etLastEnergy = p.maxEnergy;
	this.$etLastRecharge = p.forwardShieldRechargeRate;
	this.$etLastERecharge = p.energyRechargeRate;
	// note ship's initial specs (for later comparisons)
	this.$etInitialSpeed = p.maxSpeed;
	this.$etInitialThrust = p.maxThrust;
	this.$etInitialShields = p.maxForwardShield;
	this.$etInitialEnergy = p.maxEnergy;
	this.$etInitialRecharge = p.forwardShieldRechargeRate;
	this.$etInitialERecharge = p.energyRechargeRate;
}


this._installAutoDock = function() {
	var p = player.ship;
	// give the non-straying Brother free fast-docking capability
	if (!this.$etIsBellig) {
		if (p.equipmentStatus("EQ_DOCK_COMP") != "EQUIPMENT_OK") {
			p.awardEquipment("EQ_ET_AUTODOCK");
		}
	}
}


this._etSayWelcome = function() {
	var bro = this.$etBro;
	var pc = player.consoleMessage;
	var sta= player.ship.dockedStation;
	var isgl = (sta.name == "G.E.T. Guild Lodge");
	// introductory welcome to newly inducted Grocers
	if (this.$etRuns<1) {
		pc("The Galctic Guild of Elite Traders (G.E.T.)",9);
		pc("is highly pleased to bring you into our Order.",9);
		pc("We wish you great fortune and rapid advancement!",9);
		pc(" ");
	}
	// special messages on docking with a Guild Lodge
	if (isgl) {
		pc("Welcome, "+bro+", to our humble "+this.$etSystem+" Guild Lodge!",9);
		pc("Receive our Boon and blessing...",9);
		pc("And do join us at our Ceremonial before you leave us!",9);
		pc(" ",9);
	} else {
		if (!this.$etBeenBellig)
			pc("The "+this.$etSystem+" Guild of Elite Traders welcomes you!", 5);
		if (!this.$etGendered)
			pc("Guilder, please hit F4 to impart your gender...", 9);
		if (this.$etRuns<=4) {
			pc("Please check your F4 G.E.T. Interfaces often!",9);
			pc("Always check the F5-F5 Manifest on ending trading!",9);
			if (sta.isMainStation) {
				pc("Go to F4 Interface to register Name and Ship.",9);
				pc(" ");
			}
		}
	}
	// say welcome once only
	this.$etIsWelcomed = true;
}


// display ship's cargo and its purchase value
this._etPodsInHold = function(pods) {
	player.consoleMessage("In hold: "+pods+" pods ( "+formatCredits(((this.$etBoughtPrice)/10),true,true)+" )");
}


// planet name & number by 'compare radius' method
this._etGetPlanetName = function(plan) {
	var p=system.planets, name="",
	rad = plan.radius;
	if (rad!=null) {
		// run through planets in system...
		for (var i=0; i<p.length; i++) {
			if (i>0) {
				// if radii match, it's probably our planet
				if (rad===p[i].radius) name=p[i].name+" "+this.$etRoman[i+1];
			} else name=plan.name; // planet 0 is 'Prime'
		}
	} else name = plan.name; // 'vanilla' name
	return name;
}


this._etCommsTradeAdvisory = function() {
	// prices of system's key goods, plus quantity
	var ind = (system.economy<4), s=system.stations,
	pm = player.commsMessage;
	pm(""); // LF
	if (!ind) {
			for (var i=0; i<s.length; i++) if (s[i].name!="Rock Hermit")
				pm(s[i].name + ": Computers @ " + this._etMarketPrice(s[i],"computers") + " (" + this._etMarketQuantity(s[i],"computers") + ")",10);
		} else {
			for (var i=0; i<s.length; i++) if (s[i].name!="Rock Hermit")
				pm(s[i].name + ": Furs @ " + this._etMarketPrice(s[i],"furs") + " (" + this._etMarketQuantity(s[i],"furs") + ")",10);
		}
}


// number of days since first run
this._etGetDays = function() {
	var dys=0.0; 
	this.$etDaysStart=2084004.0;
	// output Lave days since induction
	this.$etDays = clock.days; // now
	dys=this.$etDays-this.$etDaysStart;
	dys=dys.toFixed(0);
	return dys;
}


// number of years since first run 
this._etGetYears = function() {
	var yrs=0.0;
	// compute Lave years since induction
	yrs=this._etGetDays();
	yrs=yrs/this.$etLaveYear;
	yrs=yrs.toFixed(3);
	return yrs;
}


// monthly bonus - grade- and credits-dependant 
this._etGetMBonus = function() {
	var bon = 0.0;
	var dys = this._etGetDays();
	// grade-dependant monthly bonus
	if ( (dys > 0) && ((dys % 30)==0) ) {
		var grd = this._etGetGrade();
		bon = (grd/22) * player.credits;
	}
	return bon;
}



// create G.E.T. Gift to Guild on the F4 Interfaces screen
this._etPrepGift = function(station) {
	station.setInterface("etGift",{
	title: "G.E.T. Gift your Station Profit to the Guild",
	category: "G.E.T.",
	summary: "Make a voluntary gift of your station profit to the Guild, to speed advancement and seal bonds.",
	callback: this._etShowGift.bind(this)
	});	
}


// Present the option to Gift Station profit to the Guild
this._etShowGift = function() {
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" Guild of Elite Traders";
	
	parameters.message = "The "+this.$etSystem+" Guild offers you the opportunity and privilege of advancing in Grade more speedily by magnanimously gifting to the G.E.T. coffers your entire profits gained here in our system - in this case "+formatCredits(this.$etTotProfit/10, true, true)+". \n\n ";

	parameters.message += this.$etBro+" and friend, you will honour and distinguish both the Guild and yourself by rendering this further contribution to G.E.T. beneficence and hegemony... You will be assured of special welcome and expeditious service in every Guild House throughout the Eight Charts. Of this your Gift, Grand Master Exoloön will learn.";
	
	parameters.choicesKey = "etGiftChoices";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		var pc = player.commsMessage;
		var pcm= player.consoleMessage;
		if (choice === "1_YES")  {
			if (!this.$etGifted) {
				if (this.$etTotProfit>0) this.$etGiftCount+=1;
				this.$etGift = this.$etTotProfit;
				this.$etGifts+=this.$etGift;
				// note previous grade here
				//this.$etLastGrade=this._etGetGrade();
				this.$etDonations+=this.$etGift;
				this.$etGifted = true;
				// grant 3-point ship enhancement
				this._etEnhanceShip(3);
				// deduct gift from player's credits
				// donation is decicredits, so convert
				player.credits -= this.$etGift/10; 
				if (this.$etGift>0) {
					pc(this.$etBro+", we thank you profusely for your munificence!",9);
					pc("Your speedy advancement is secure!",9);
					pcm(this.$etBro+", we grant you a 3-point ship enhancement.",9);
				} else pc("Blessings, "+this.$etBro,9);
			} else pc("Please give to G.E.T. at your next port of call!",9);
			// update Manifest
			this._etShowStatus();
		}
	}
}


	
// create G.E.T. Best Trade Resetter on the F4 Interfaces screen
this._etPrepResetter = function(station) {
	station.setInterface("etResetter",{
	title: "G.E.T. Best Trade Resetter",
	category: "G.E.T.",
	summary: "Reset your Best Trade to the profit gained in this system.",
	callback: this._etShowResetter.bind(this)
	});	
}


// Present the option to reset Best Trade to the profit made here
this._etShowResetter = function() {
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" Guild of Elite Traders";
	
	parameters.message = "The "+this.$etSystem+" Guild of Elite Traders offers you the opportunity to reset your Best Trade, as displayed on your ship's Manifest screen, to the profit you have just gained here in our system - in this case "+formatCredits(this.$etTotProfit/10, true, true)+". \n\n ";

	parameters.message += "In fact you would honour us by doing so...";
	
	parameters.choicesKey = "etResetMaxTradeChoices";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  {
			this.$etMaxTrade=this.$etTotProfit;
			this.$etMaxTSystem=this.$etSystem;		
			this.$etMaxTGoods=this.$etCommodities;		
			// the ship we maxed it in
			var p=player.ship;
			this.$etMaxTShip = p.shipClassName;
			this.$etMaxTShipName = p.shipUniqueName;
			this.$etMaxTShipTC = p.cargoSpaceCapacity;
			player.commsMessage("Maximum Trade reset. Please check the Manifest.");
			// update Manifest
			this._etShowStatus();
		}
	}
}


// create G.E.T. Master Advisory on the F4 Interfaces screen
this._etPrepAdvisory = function(station) {
	station.setInterface("etAdvisory",{
	title: "G.E.T. Master Advisory",
	category: "G.E.T.",
	summary: "Salutation and advice from the Master of the "+this.$etSystem+" Guild of Elite Traders",
	callback: this._etShowAdvisory.bind(this)
	});	
}


// Salutation and advice from the station Guild Master
this._etShowAdvisory = function() {
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" Guild of Elite Traders";
	
	var grade = this._etGetGrade(), title=this.$etGETTitle[grade], lim=this.$etGETTitle.length;
	var grovel ="", pregrovel="";
	var greet = "The "+this.$etSystem+" Guild of Elite Traders bids their "+this.$etBro+" "+player.name+" a hearty welcome to their Guild Home and trusts ";
	if ((grade>=5) && (grade<11)) { greet = title + ", you honour our Guild Home by your visit! If only we had been better prepared for your arrival... " + this.$etSystem + " G.E.T. nevertheless hopes ";
	grovel = "Anything you might need, Master, they are here to serve you."; }
	if ((grade>10)) { greet = title + "! your worshipful presence humbles our poor and wretched Guild Home, yet your visit ennobles us! If only we had been informed that your Honour would be arriving... " + this.$etSystem + " G.E.T. nevertheless prays ";
	grovel = "Anything, anything you require, Exalted One, they are here to serve, as are we all."; }
	
	parameters.message = greet + " this sojourn among us will be advantageous... Trade well! May the GETTING exceed the Taking! \n\n";
	
	// G.E.T. contact (Assessor)
	parameters.message += "Master " + this.$etContact + " is your Assessor and contact for your stopover. "+grovel+" \n\n";
	
	// Planets with stations
	var plan = "", p=system.planets, sta="", s=system.stations;
	var i = 0; // count the planets
	if ((p.length>1) && (this.$etNoob=="no")) { 
		for (i=0; i<p.length; i++) {
			if (i>0) plan += p[i].name+" "+this.$etRoman[i+1]+"  ";
			else plan += p[i].name+"  ";
		}
		// don't say planets if too many stations (makes space!)
		if (i<4)
			parameters.message += "Our planets with stations are: "+plan+"\n\n"; 
	
		/*for (i=0; i<s.length; i++) if (s[i].name!="Rock Hermit") sta += s[i].name + "  ";
		parameters.message += "Our stations are: "+sta+"\n\n";*/ 
	
		// prices of system's prime commodities, plus quantity
		var ind = (system.economy<4);
		if (ind) {
			for (i=0; i<s.length; i++) { 
				if (s[i].name!="Rock Hermit") { 
					parameters.message += "Computers at our "+ s[i].name + " cost " + this._etMarketPrice(s[i],"computers") + " (" + this._etMarketQuantity(s[i],"computers") + ") \n";
					parameters.message += "Luxuries at our "+ s[i].name + " cost " + this._etMarketPrice(s[i],"luxuries") + " (" + this._etMarketQuantity(s[i],"luxuries") + ") \n\n";
				}
			}
		} else {
			for (i=0; i<s.length; i++) { 
				if (s[i].name!="Rock Hermit") {
					parameters.message += "Furs at our "+ s[i].name + " cost " + this._etMarketPrice(s[i],"furs") + " (" + this._etMarketQuantity(s[i],"furs") + ") \n";
					parameters.message += "Liquors at our "+ s[i].name + " cost " + this._etMarketPrice(s[i],"liquor_wines") + " (" + this._etMarketQuantity(s[i],"liquor_wines") + ") \n\n";
				}
			}
		}
		parameters.message += "\n";
	}
	
	if (grade<6)  parameters.message += "To business, "+this.$etBro+"... "; else
	if (grade<11) parameters.message += "To business, then, Friend and "+this.$etBro+"... "; else
	if (grade<lim) parameters.message += "To business, then, o Perfected "+this.$etBro+" and - dare we hope? - Friend... ";
	
	if (this.$etNoob=="yes") {
		var p = player.ship;
		var sname = p.shipUniqueName; 
		var sclass = p.shipClassName;

		parameters.message += "You may note with irony that G.E.T. cares little whether Galcop deems your goods illegal... We have small truck with that legislative body. With us, your record is always clean, and all trades legitimate in our eyes.  \n\n"

		parameters.message += "Words of advice are never amiss, you'll agree? ";
		
		parameters.message += "One abiding Rule governs our Order: Trade well, refrain from combat, aid your Brothers. Above all, do not kill. ";
	
		parameters.message += "Remember it - advance in Grade and wealth. Ignore it, and risk our silence. Then only Penance will bring you back. \n\n";
		
		if (this.$etStrict) var strctMsg = "Above Grade 1, "; else strctMsg="";
		parameters.message += "Your craft has a 'weapons offline' switch: "+strctMsg+"use it after witch and watch threats fly by with J-drive engaged. G.E.T. provides priority docking to all Brothers; in the shipyard, our Master mechs and techs are unrivalled. Your "+sclass+" will flourish! ";
	} 
	else if (!this.$etMarketObserver) 
		parameters.message += "As it forever has been, the Market Observer and Market Inquirer of Fra Spara are almost de rigueur. Do not exit a space-dock without these! Seek a Torus to Sun Drive and our Advanced Space Compass once you have your Large Cargo Bay and Goods Containers, obtaining which is now your prime concern. \n \n";

	parameters.choicesKey = "etAcknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES") { 
			// we only need to read the noob text once!
			this.$etNoob = "no";
			player.commsMessage("Luck in the Markets!");
		}
	}
}


// create G.E.T. Sales Advisory on the F4 Interfaces screen
this._etPrepSales = function(station) {
	station.setInterface("etSales",{
	title: "G.E.T. Guild Lodge Sales Advisory",
	category: "G.E.T.",
	summary: "Salutation and sales advice from the "+this.$etSystem+" Lodge Master",
	callback: this._etShowSales.bind(this)
	});	
}


// Sales advice from the Guild Lodge Master
this._etShowSales = function() {
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" Guild Lodge";
	
	parameters.message = this.$etBro + " "+player.name+", we are honoured and delighted to welcome you to our humble Guild Lodge. As I'm sure time presses on you, here without further ado are our system sell-prices for the most popular traded goods... \n\n";
	
	var plan = "", p=system.planets, sta="", s=system.stations;
		// prices of system's prime commodities, plus quantity
		var ind = (system.economy<4);
		if (ind) {
			for (var i=0; i<s.length; i++) { 
				if (s[i].name!="Rock Hermit") { 
					parameters.message += "Furs at our "+ s[i].name + " sell at " + this._etMarketPrice(s[i],"furs") + " (" + this._etMarketQuantity(s[i],"furs") + ") \n";
					parameters.message += "Liquors at our "+ s[i].name + " sell at " + this._etMarketPrice(s[i],"liquor_wines") + " (" + this._etMarketQuantity(s[i],"liquor_wines") + ") \n\n";
				}
			}
		} else {
			for (var i=0; i<s.length; i++) { 
				if (s[i].name!="Rock Hermit") {
					parameters.message += "Computers at our "+ s[i].name + " sell at " + this._etMarketPrice(s[i],"computers") + " (" + this._etMarketQuantity(s[i],"computers") + ") \n";
					parameters.message += "Luxuries at our "+ s[i].name + " sell at " + this._etMarketPrice(s[i],"luxuries") + " (" + this._etMarketQuantity(s[i],"luxuries") + ") \n\n";
				}
			}
		}
		parameters.message += "\n";
	
	var grade=this._etGetGrade();
	if (grade<6)  parameters.message += "To business, "+this.$etBro+"... "; else
	if (grade<11) parameters.message += "To business, then, Friend and "+this.$etBro+"... "; else
	if (grade<lim) parameters.message += "To business, then, o Perfected "+this.$etBro+" and - dare we hope? - Friend... ";
	

	parameters.choicesKey = "etAcknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("Luck in the Markets!");
	}
}



// Vow of Good Brotherhood
this._etPrepVow = function(station) {
	station.setInterface("etVow",{
	title: "G.E.T. Vow of Good Brotherhood",
	category: "G.E.T.",
	summary: "Make a Vow of Good Brotherhood to the Master of the "+this.$etSystem+" Guild of Elite Traders",
	callback: this._etShowVow.bind(this)
	});	
}


// Present the option to make a Vow of Good Brotherhood
this._etShowVow = function() {
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" Guild of Elite Traders";
	
	parameters.message = "We observed with sadness your straying from the Path of Good Brotherhood. You have killed - not once, but multiple times. Yet we understand your urges and the weakness of the newly inducted. For this reason, the "+this.$etSystem+" Guild of Elite Traders offers you the opportunity to mend errant ways... \n\n ";
	
	parameters.message += "The Masters of the Guild are prepared to reinstate you as a full "+this.$etBro+" and restore all privileges of the G.E.T., indeed to forget your infractions, provided you demonstrate self-discipline and, above all, mercy in your future conduct on the space-lanes.\n\n ";
	
	parameters.message += "Remember the Rule: Do not kill. It is our only Rule. We do not ask why you broke it, but do demand that you respect and live by it. \n\n ";
	
	parameters.message += "Commander "+player.name+", are you prepared now to renew your Vow of Good Brotherhood with the Guild? \n\n ";

	this.$etVowing = true;
	parameters.choicesKey = "etVowChoices";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  {
			// reinstate Brother's privileges
			this.$etIsBellig = false;
			this.$etBeenBellig = false;
			this.$etKillCount = 0;
			this.$etVowCount ++;
			player.ship.bounty = 0;
			player.consoleMessage("Then all is forgiven and we welcome you back.",5);
		} else player.consoleMessage("Then our backs must remain turned. Fare well.",5);
	}
}


// G.E.T. ship condition and status report
this._etPrepShipStatus = function(station) {
	station.setInterface("etShipStatus",{
	title: "G.E.T. Ship Status Report",
	category: "G.E.T.",
	summary: "The current state of your G.E.T. ship enhancements.",
	callback: this._etShowShipStatus.bind(this)
	});	
}


// Display status of G.E.T. ship enhancements
this._etShowShipStatus = function() {
	var p = player.ship;
	var sname = p.shipUniqueName; 
	var sclass = p.shipClassName;
	
	if ((sname!=null) && (sname!="")) sname = " '"+sname+"' ";
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" G.E.T. Shipyard";
	
	parameters.message = "The "+this.$etSystem+" Guild of Elite Traders bids you welcome to our shipyard and hopes that our services to your fine "+sclass+sname+" meet with approval. Since your induction, technical enhancements to her systems have included: \n\n";

	parameters.message += "Nominal speed: "+this.$etInitialSpeed+"  -->>  Current speed: "+p.maxSpeed+" \n\n";
	
	parameters.message += "Nominal thrust: "+this.$etInitialThrust+"  -->>  Current thrust: "+p.maxThrust+" \n\n";
	
	parameters.message += "Nominal shields: "+this.$etInitialShields+"  -->>  Current shields: "+p.maxForwardShield+" \n\n";
	
	parameters.message += "Nominal energy: "+this.$etInitialEnergy+"  -->>  Current energy: "+p.maxEnergy+" \n\n";
		
	parameters.message += "Nominal recharge: "+this.$etInitialERecharge.toFixed(2)+"  -->>  Current recharge: "+p.energyRechargeRate.toFixed(2)+" \n\n";

	parameters.choicesKey = "etAcknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("Be safe in the Lane!");
	}
}


// price of a good at a given station, in cr
this._etMarketPrice = function(sta, good) {
	var price=0.0, mar=sta.market;
	price = mar[good].price/10;
	return price.toFixed(1);
}


// quantity of a good at a given station
this._etMarketQuantity = function(sta, good) {
	var quant=0, mar=sta.market;
	quant = mar[good].quantity;
	return quant;
}


/* Note: this helper function is from phkb's Equipment Storage OXP */
// returns the player's target system (1.80) or the next jump to their target system (1.82+)
this._TargetSystem = function _TargetSystem() {
	if (player.ship.hasOwnProperty("nextSystem")) return player.ship.nextSystem;

	var target = player.ship.targetSystem;

	if (oolite.compareVersion("1.81") < 0 && player.ship.hasEquipmentProviding("EQ_ADVANCED_NAVIGATIONAL_ARRAY") === true) {
		// in 1.81 or greater, the target system could be more than 7 ly away. It becomes, essentially, the final destination.
		// there could be multiple interim stop points between the current system and the target system.
		// the only way to get this info is to recreate a route using the same logic as entered on the ANA, and pick item 1
		// from the list. That should be the next destination in the list.
		if (system.ID === -1) {
			var myRoute = System.infoForSystem(galaxyNumber, this._lastSource).routeToSystem(System.infoForSystem(galaxyNumber, target), player.ship.routeMode);
		} else {
			var myRoute = System.infoForSystem(galaxyNumber, global.system.ID).routeToSystem(System.infoForSystem(galaxyNumber, target), player.ship.routeMode);
		}
		if (myRoute && myRoute.route.length >= 1) {
			target = myRoute.route[1];
		}
	}

	return target;
}



// create G.E.T. 'Buber's Beats' page 
this._etPrepBeats = function(station) {
	station.setInterface("etBeats",{
	title: "G.E.T. Milk or Cream? - Buber's Beats",
	category: "G.E.T.",
	summary: "Solid examples and advice from a favoured Brother with our exalted Grand Master's endorsement.",
	callback: this._etShowBeats.bind(this)
	});	
}


// Buber's Beats - walkthrough and advice
this._etShowBeats = function() {
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" Guild of Elite Traders";
	
	parameters.message = "Your Friend and Brother, Master Traveller Fens Buber, offers you these creamy beats with our exalted Grand Master's approval: \n\n";

	parameters.message += "Spaceway L1/L2, Sector One, Galaxy One \n";
	parameters.message += "----------------------------------------------------------- \n\n";

	parameters.message += "0. (Lave-->Zaonce-->Isinor-->) \n";
	parameters.message += "1. Qutiri-->Isinor-->Ensoreus-->Ararus \n";
	parameters.message += "2. Zarece-->Isence \n";
	parameters.message += "3. Tiinlebi-->Anlama-->Begeabi \n";
	parameters.message += "4. Xexedi-->Laenin-->Lerelace \n";
	parameters.message += "5. Razaar-->Zadies-->Anarlaqu-->Vetitice \n";
	parameters.message += "6. Zasoceat-->Riantiat-->Teraed-->Bivea-->Enzaer \n";
	parameters.message += "7. Tianve/Anle-->Teanrebi \n";
	parameters.message += "8. Malama-->Qudira-->Inines-->Qudira-->Esbiza \n\n";

	parameters.message += "Repeat and vary at will, or do the grand tour of these 29 systems. Buy Computers (+luxuries) in Rich Industrials and Furs (+liquor-wines) in Poor Agriculturals. \n\n";

	parameters.choicesKey = "etAcknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("Trade well and wisely, "+this.$etBro+"!");
	}
}



// Prepare Gender request
this._etPrepGender = function(station) {
	station.setInterface("etGender",{
	title: "G.E.T. Your gender, gentle Guilder?",
	category: "G.E.T.",
	summary: "The Guild Master requests to know whether you are female, male, or bi-gendered.",
	callback: this._etShowGender.bind(this)
	});	
}


// Present the option to impart your gender
this._etShowGender = function() {
	
	var parameters = new Object();
	
	parameters.title = "The "+this.$etSystem+" Guild of Elite Traders";
	
	parameters.message = "Profuse and embarrassed apologies, but the Guild Master of "+this.$etSystem+" has been unable to determine your gender... Would you perhaps be willing to impart it to me, his assistant, so that no faux pas in future protocol will occur? \n\n ";
	
	parameters.message += "If female, we shall be pleased and honoured to call you 'Sister'; if male - 'Brother'; if bi-, tri-, or null-gendered - 'Sibling'... or simply continue with 'Guilder' if you prefer. \n ";
	
	parameters.choicesKey = "etGenderChoices";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_FEMALE") this.$etBro="Sister"; else
		if (choice === "2_MALE") this.$etBro="Brother"; else
		if ((choice === "3_BOTH") || (choice== "4_NULL")) this.$etBro="Sibling"; else
			this.$etBro = "Guilder";
		if (this.$etBro==="Sibling") player.consoleMessage("Thank you. Then you shall be our 'Sibling'.",7); else player.consoleMessage("Thank you "+this.$etBro+". We will remember it.",7);
		this.$etGendered=true;
	}
}


Scripts/fe-script.js
"use strict";
this.name = "script.js";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";


// make sure that these ships are always present at Lave
this.startUpComplete = function() {
	if (system.name == "Lave") {
		// Adder
		this._feAddShip("adder-player", "Adder FE", 73000);
		// Gecko
		this._feAddShip("gecko-player", "Gecko FE", 66000);
		// Krait
		this._feAddShip("krait-player", "Krait FE", 50000);
		// Sidewinder
		this._feAddShip("sidewinder-player", "Sidewinder FE", 44000);
		// correct Oolite's mis-naming of the Cobra III in Normal start,
		// and also provide a Cobby III clone - because Lave Shipyard _can_
		// (the adventuresome player gets an extra 100 cr to play with too)
		if (player.ship.dataKey == "cobra3-player") {
			player.ship.shipClassName = "Cobra Mk 3 FE";
			this._feCloneShip();
		}
	}
}


this.shipDockedWithStation = function(station) {
	// counter the rarity of the Asp Explorer
	if (system.techLevel>10) this._feAddShip("asp-player", "Asp Explorer FE", 187000);
}


this._feAddShip = function(id,name,pr) { 
	system.mainStation.addShipToShipyard({ 
		short_description: name+": standard customer model, price "+formatCredits(pr,true,true)+".", 
		shipdata_key: id, 
		price: pr, 
		personality:0,
		extras:[""]
	});
}


// leave an identical ship at the shipyard
// in case player wishes to reset its specs
this._feCloneShip = function() {
	if (oolite.versionString>"1.88") {
		var pr = player.ship.price * 0.746;
		system.mainStation.addShipToShipyard({ 
			short_description: system.name +" Shipyard offers you this clone of your ship, gratis. Why? - Because we _can_", 
			shipdata_key: player.ship.dataKey, 
			price: pr, 
			personality:0,
			extras:[""]
		});
	}
}

Scripts/gc1_script.js
"use strict";
this.name = "Goods Container 10 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "2.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	// keep tally of pylon accessories bought
	this.$gc1Count++;
    // and don't let them exceed ship's pylon-capacity
	if ((equipment == "EQ_GC1_MINE") && (this.$gc1Count<=this.$gc1MCap)) {
		player.ship.cargoSpaceCapacity += 10;
		this.$gc1Containers++;
		pc("Modifying pylon hardpoints for container clamping...",9);
		pc("Fitting 10 TC Class Container #"+this.$gc1Containers+"...",9);
		pc("F4 'Your FE Shipyards' to check your Licence.",9);
	} else
	// unmount & sell cancels all container additions
	if (equipment == "EQ_MISSILE_REMOVAL") {
		player.ship.cargoSpaceCapacity -= this.$gc1Containers*10;
		if (this.$gc1Containers>0) {
			pc("Removing all 10 TC Class Containers...",9);
			pc("Restoring pylon hardpoints for weapons-use...",9);
		}
		if ((this.$gc1Containers>0) && (!this.$gc1HFExempt)) {
			// dismantling fee
			var dft = this.$gc1Containers*this.$gc1DismantlingFee;
			this.$gc1DismantlingFeeTotal += dft;
			player.credits -= dft;
			pc("Dismantling Fee: "+dft+" cr",9);
		}
		this.$gc1Count = 0;
		this.$gc1Containers = 0;
		// reset system-to-system runs w/containers
		this.$gc1Runs = 0;
		// reset fee totals
		this.$gc1HandlingFeeTotal = 0;
		this.$gc1MaintenanceFeeTotal = 0;
	}
}


this.playerBoughtNewShip = function(ship, price) {
	// missile capacity (not exceed)
	this.$gc1MCap = player.ship.missileCapacity;
	this.$gc1Count = 0;
	this.$gc1Containers = 0;
}


this.equipmentRemoved = function(equipmentKey) {
    if (equipmentKey == "EQ_GC1_MINE") {
		player.ship.cargoSpaceCapacity -= 10;
		this.$gc1Containers--;	
		player.consoleMessage("10 TC Goods Container removed.",5);
	}
}


this.shipReleasedEquipment = function(mine) {
	this.$gc1Count--;
    if (mine == "EQ_GC1_MINE") {
		player.ship.cargoSpaceCapacity -= 10;
		this.$gc1Containers--;
		player.commsMessage("10 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 10000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.shipFiredMissile = function(missile, target) {
	this.$gc1Count--;
    if (missile == "EQ_GC1_MINE") {
		player.ship.cargoSpaceCapacity -= 10;
		this.$gc1Containers--;	
		player.commsMessage("10 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 10000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.startUpComplete = function () {
	var pc = player.consoleMessage;
	// missile capacity (not exceed)
	this.$gc1MCap = player.ship.missileCapacity;
	this.$gc1Count = player.ship.missiles.length;
	// Load cargo space, missile & container counts if present
	if (missionVariables.gc1Cargo != null) 
		player.ship.cargoSpaceCapacity = missionVariables.gc1Cargo;
	if (missionVariables.gc1Count != null)
		this.$gc1Count = missionVariables.gc1Count;
	if (missionVariables.gc1Containers != null) 
		this.$gc1Containers = missionVariables.gc1Containers;
	// Load total fees taken
	if (missionVariables.gc1HandlingFeeTotal != null)
		this.$gc1HandlingFeeTotal = missionVariables.gc1HandlingFeeTotal;
	if (missionVariables.gc1HandlingPaid != null)
		this.$gc1HandlingPaid = missionVariables.gc1HandlingPaid;
	if (missionVariables.gc1MaintenanceFeeTotal != null)
		this.$gc1MaintenanceFeeTotal = missionVariables.gc1MaintenanceFeeTotal;
	if (missionVariables.gc1DismantlingFeeTotal != null)
		this.$gc1DismantlingFeeTotal = missionVariables.gc1DismantlingFeeTotal; 
    // Load system-to-system runs w/container
	if (missionVariables.gc1Runs != null)
		this.$gc1Runs = missionVariables.gc1Runs;
	// Load Handling fee count
	if (missionVariables.gc1HandlingCount != null)
		this.$gc1HandlingCount = missionVariables.gc1HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.gc1HFExempt != null)
		this.$gc1HFExempt = missionVariables.gc1HFExempt;
	// Load Maintenance fee count
	if (missionVariables.gc1MaintenanceCount != null)
		this.$gc1MaintenanceCount = missionVariables.gc1MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// TEST
	var sta = player.ship.dockedStation;
	if ((this.$gc1Containers<this.$gc1MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	// prepare container Account screen
	if (this.$gc1Containers>0) this._gc1PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$gc1Containers>0) this._gc1PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$gc1ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$gc1ET = true;
	// TEST	
	if (this.$gc1ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$gc1FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$gc1FES = true;
	// TEST	
	if (this.$gc1ET) log(this.name, "Finds FE Ships Player present");
	// missile capacity (not exceed)
	this.$gc1MCap = 0;
	// pylon-use count
	this.$gc1Count = 0;
	// container count
	this.$gc1Containers = 0;
	// purchase cost of container in cr
	this.$gc1Cost = 10000;
	// handling fee
	this.$gc1HandlingFee = 0.005*this.$gc1Cost; // 0.005 of cost
	this.$gc1HandlingFeeTotal = 0;
	this.$gc1HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$gc1HandlingCount = 0;
	this.$gc1HFExempt = "no";
	// maintenance fee
	this.$gc1MaintenanceFee = 0.05*this.$gc1Cost; // 0.05 of cost
	this.$gc1MaintenanceFeeTotal = 0;
	this.$gc1MaintenancePaid = "no" // or "yes"
	this.$gc1MaintenanceInterval = 10; // in runs (according to cost)
	this.$gc1MaintenanceCount = 0;
	// dismantling fee
	this.$gc1DismantlingFee = 0.1*this.$gc1Cost; // 0.1 of cost
	this.$gc1DismantlingFeeTotal = 0.0;
	// system-to-system runs w/container
	this.$gc1Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.gc1Count = this.$gc1Count;
	missionVariables.gc1Cargo = player.ship.cargoSpaceCapacity;
	missionVariables.gc1Containers = this.$gc1Containers;
	// save total fees taken
	missionVariables.gc1HandlingFeeTotal = this.$gc1HandlingFeeTotal;
	missionVariables.gc1MaintenanceFeeTotal = this.$gc1MaintenanceFeeTotal;
	missionVariables.gc1DismantlingFeeTotal = this.$gc1DismantlingFeeTotal;
	missionVariables.gc1HandlingPaid = this.$gc1HandlingPaid;
	// system-to-system runs w/container
	missionVariables.gc1Runs =this.$gc1Runs;
	// handling fee count
	missionVariables.gc1HandlingCount = this.$gc1HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.gc1HFExempt = this.$gc1HFExempt;
	// maintenance fee count
	missionVariables.gc1MaintenanceCount = this.$gc1MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$gc1HFExempt;
	// check we have containers, the fee is not paid, and we're not exempt
	if ((this.$gc1Containers>0) && (this.$gc1HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$gc1Containers; x++)
			fee += this.$gc1HandlingFee;
		// record fee and debit trader's account
		this.$gc1HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$gc1HandlingPaid = "yes";
		pc("10 TC Container handling fees: "+fee+" cr",9);
		this.$gc1HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$gc1Containers>0) this._gc1DoMaintenance();

	// TEST
	if ((this.$gc1Containers<this.$gc1MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	
	// prepare container Account and Licence page
	if (this.$gc1Containers>0) this._gc1PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$gc1Containers>0) this._gc1PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$gc1HandlingPaid = "no";
	this.$gc1Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._gc1DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$gc1Runs;
	var intv = this.$gc1MaintenanceInterval;
	var mfee = this.$gc1MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x containers
		var fee = 0;
		for (var x=1; x<= this.$gc1Containers; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$gc1MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("10 TC Container Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$gc1MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._gc1PrepAcc = function(station) {
	station.setInterface("gc1Acc",{
	title: "Your FE Shipyards 10 TC Container Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 10 TC Goods Container account screen shows terms, fees paid, load, and other useful information.",
	callback: this._gc1ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._gc1ShowAcc = function() {
	var hfc = this.$gc1HandlingCount;
	var mfc = this.$gc1MaintenanceCount;
	var mfi = this.$gc1MaintenanceInterval;
	var hft = this.$gc1HandlingFeeTotal;
	var mft = this.$gc1MaintenanceFeeTotal;
	var dft = this.$gc1DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$gc1Containers>0) 
		parameters.message +="Your Account and Licence for 10 TC Class Goods Containers x "+this.$gc1Containers+": \n\n"; 
	 else
		parameters.message +="You have no 10 TC Class Containers licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our containers are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Container account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylons for weapons-use. \n";
	
	parameters.choicesKey = "gc1Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._gc1PrepEx = function(station) {
	station.setInterface("gc1Ex",{
	title: "Your FE Shipyards Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 10-ton container class." ,
	callback: this._gc1ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._gc1ShowEx = function() {
	var priv = ((this.$gc1ET)||(this.$gc1FES));
	var privo = "";
	if (this.$gc1FES) privo="FE shipowner";
	if (this.$gc1ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 10 TC container fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "gc1YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$gc1HFExempt = "yes"; else this.$gc1HFExempt = "no";
		} else this.$gc1HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}



Scripts/gc2_script.js
"use strict";
this.name = "Goods Container 20 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "2.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	// keep tally of pylon accessories bought
	this.$gc2Count++;
    // and don't let them exceed ship's pylon-capacity
	if ((equipment == "EQ_GC2_MINE") && (this.$gc2Count<=this.$gc2MCap)) {
		player.ship.cargoSpaceCapacity += 20;
		this.$gc2Containers++;
		pc("Modifying pylon hardpoints for container clamping...",9);
		pc("Fitting 20 TC Class Container #"+this.$gc2Containers+"...",9);
		pc("F4 'Your FE Shipyards' to check your Licence.",9);
	} else
	// unmount & sell cancels all container additions
	if (equipment == "EQ_MISSILE_REMOVAL") {
		player.ship.cargoSpaceCapacity -= this.$gc2Containers*20;
		if (this.$gc2Containers>0) {
			pc("Removing all 20 TC Class Containers...",9);
			pc("Restoring pylon hardpoints for weapons-use...",9);
		}
		if ((this.$gc2Containers>0) && (!this.$gc2HFExempt)) {
			// dismantling fee
			var dft = this.$gc2Containers*this.$gc2DismantlingFee;
			this.$gc2DismantlingFeeTotal += dft;
			player.credits -= dft;
			pc("Dismantling Fee: "+dft+" cr",9);
		}
		this.$gc2Count = 0;
		this.$gc2Containers = 0;
		// reset system-to-system runs w/containers
		this.$gc2Runs = 0;
		// reset fee totals
		this.$gc2HandlingFeeTotal = 0;
		this.$gc2MaintenanceFeeTotal = 0;
	}
}


this.playerBoughtNewShip = function(ship, price) {
	// missile capacity (not exceed)
	this.$gc2MCap = player.ship.missileCapacity;
	this.$gc2Count = 0;
	this.$gc2Containers = 0;
}


this.equipmentRemoved = function(equipmentKey) {
    if (equipmentKey == "EQ_GC2_MINE") {
		player.ship.cargoSpaceCapacity -= 20;
		this.$gc2Containers--;	
		player.consoleMessage("20 TC Goods Container removed.",5);
	}
}


this.shipReleasedEquipment = function(mine) {
	this.$gc2Count--;
    if (mine == "EQ_GC2_MINE") {
		player.ship.cargoSpaceCapacity -= 20;
		this.$gc2Containers--;
		player.commsMessage("20 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 20000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.shipFiredMissile = function(missile, target) {
	this.$gc2Count--;
    if (missile == "EQ_GC2_MINE") {
		player.ship.cargoSpaceCapacity -= 20;
		this.$gc2Containers--;	
		player.commsMessage("20 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 20000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.startUpComplete = function () {
	var pc = player.consoleMessage;
	// missile capacity (not exceed)
	this.$gc2MCap = player.ship.missileCapacity;
	this.$gc2Count = player.ship.missiles.length;
	// Load cargo space, missile & container counts if present
	if (missionVariables.gc2Cargo != null) 
		player.ship.cargoSpaceCapacity = missionVariables.gc2Cargo;
	if (missionVariables.gc2Count != null)
		this.$gc2Count = missionVariables.gc2Count;
	if (missionVariables.gc2Containers != null) 
		this.$gc2Containers = missionVariables.gc2Containers;
	// Load total fees taken
	if (missionVariables.gc2HandlingFeeTotal != null)
		this.$gc2HandlingFeeTotal = missionVariables.gc2HandlingFeeTotal;
	if (missionVariables.gc2HandlingPaid != null)
		this.$gc2HandlingPaid = missionVariables.gc2HandlingPaid;
	if (missionVariables.gc2MaintenanceFeeTotal != null)
		this.$gc2MaintenanceFeeTotal = missionVariables.gc2MaintenanceFeeTotal;
	if (missionVariables.gc2DismantlingFeeTotal != null)
		this.$gc2DismantlingFeeTotal = missionVariables.gc2DismantlingFeeTotal; 
    // Load system-to-system runs w/container
	if (missionVariables.gc2Runs != null)
		this.$gc2Runs = missionVariables.gc2Runs;
	// Load Handling fee count
	if (missionVariables.gc2HandlingCount != null)
		this.$gc2HandlingCount = missionVariables.gc2HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.gc2HFExempt != null)
		this.$gc2HFExempt = missionVariables.gc2HFExempt;
	// Load Maintenance fee count
	if (missionVariables.gc2MaintenanceCount != null)
		this.$gc2MaintenanceCount = missionVariables.gc2MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// TEST
	var sta = player.ship.dockedStation;
	if ((this.$gc2Containers<this.$gc2MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	// prepare container Account screen
	if (this.$gc2Containers>0) this._gc2PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$gc2Containers>0) this._gc2PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$gc2ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$gc2ET = true;
	// TEST	
	if (this.$gc2ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$gc2FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$gc2FES = true;
	// TEST	
	if (this.$gc2ET) log(this.name, "Finds FE Ships Player present");
	// missile capacity (not exceed)
	this.$gc2MCap = 0;
	// pylon-use count
	this.$gc2Count = 0;
	// container count
	this.$gc2Containers = 0;
	// purchase cost of container in cr
	this.$gc2Cost = 20000;
	// handling fee
	this.$gc2HandlingFee = 0.005*this.$gc2Cost; // 0.005 of cost
	this.$gc2HandlingFeeTotal = 0;
	this.$gc2HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$gc2HandlingCount = 0;
	this.$gc2HFExempt = "no";
	// maintenance fee
	this.$gc2MaintenanceFee = 0.05*this.$gc2Cost; // 0.05 of cost
	this.$gc2MaintenanceFeeTotal = 0;
	this.$gc2MaintenancePaid = "no" // or "yes"
	this.$gc2MaintenanceInterval = 20; // in runs (according to cost)
	this.$gc2MaintenanceCount = 0;
	// dismantling fee
	this.$gc2DismantlingFee = 0.1*this.$gc2Cost; // 0.1 of cost
	this.$gc2DismantlingFeeTotal = 0.0;
	// system-to-system runs w/container
	this.$gc2Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.gc2Count = this.$gc2Count;
	missionVariables.gc2Cargo = player.ship.cargoSpaceCapacity;
	missionVariables.gc2Containers = this.$gc2Containers;
	// save total fees taken
	missionVariables.gc2HandlingFeeTotal = this.$gc2HandlingFeeTotal;
	missionVariables.gc2MaintenanceFeeTotal = this.$gc2MaintenanceFeeTotal;
	missionVariables.gc2DismantlingFeeTotal = this.$gc2DismantlingFeeTotal;
	missionVariables.gc2HandlingPaid = this.$gc2HandlingPaid;
	// system-to-system runs w/container
	missionVariables.gc2Runs =this.$gc2Runs;
	// handling fee count
	missionVariables.gc2HandlingCount = this.$gc2HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.gc2HFExempt = this.$gc2HFExempt;
	// maintenance fee count
	missionVariables.gc2MaintenanceCount = this.$gc2MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$gc2HFExempt;
	// check we have containers, the fee is not paid, and we're not exempt
	if ((this.$gc2Containers>0) && (this.$gc2HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$gc2Containers; x++)
			fee += this.$gc2HandlingFee;
		// record fee and debit trader's account
		this.$gc2HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$gc2HandlingPaid = "yes";
		pc("20 TC Container handling fees: "+fee+" cr",9);
		this.$gc2HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$gc2Containers>0) this._gc2DoMaintenance();

	// TEST
	if ((this.$gc2Containers<this.$gc2MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	
	// prepare container Account and Licence page
	if (this.$gc2Containers>0) this._gc2PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$gc2Containers>0) this._gc2PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$gc2HandlingPaid = "no";
	this.$gc2Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._gc2DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$gc2Runs;
	var intv = this.$gc2MaintenanceInterval;
	var mfee = this.$gc2MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x containers
		var fee = 0;
		for (var x=1; x<= this.$gc2Containers; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$gc2MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("20 TC Container Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$gc2MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._gc2PrepAcc = function(station) {
	station.setInterface("gc2Acc",{
	title: "Your FE Shipyards 20 TC Container Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 20 TC Goods Container account screen shows terms, fees paid, load, and other useful information.",
	callback: this._gc2ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._gc2ShowAcc = function() {
	var hfc = this.$gc2HandlingCount;
	var mfc = this.$gc2MaintenanceCount;
	var mfi = this.$gc2MaintenanceInterval;
	var hft = this.$gc2HandlingFeeTotal;
	var mft = this.$gc2MaintenanceFeeTotal;
	var dft = this.$gc2DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$gc2Containers>0) 
		parameters.message +="Your Account and Licence for 20 TC Class Goods Containers x "+this.$gc2Containers+": \n\n"; 
	 else
		parameters.message +="You have no 20 TC Class Containers licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our containers are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Container account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylons for weapons-use. \n";
	
	parameters.choicesKey = "gc2Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._gc2PrepEx = function(station) {
	station.setInterface("gc2Ex",{
	title: "Your FE Shipyards Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 20-ton container class." ,
	callback: this._gc2ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._gc2ShowEx = function() {
	var priv = ((this.$gc2ET)||(this.$gc2FES));
	var privo = "";
	if (this.$gc2FES) privo="FE shipowner";
	if (this.$gc2ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 20 TC container fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "gc2YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$gc2HFExempt = "yes"; else this.$gc2HFExempt = "no";
		} else this.$gc2HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}



Scripts/gc3_script.js
"use strict";
this.name = "Goods Container 30 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "2.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	// keep tally of pylon accessories bought
	this.$gc3Count++;
    // and don't let them exceed ship's pylon-capacity
	if ((equipment == "EQ_GC3_MINE") && (this.$gc3Count<=this.$gc3MCap)) {
		player.ship.cargoSpaceCapacity += 30;
		this.$gc3Containers++;
		pc("Modifying pylon hardpoints for container clamping...",9);
		pc("Fitting 30 TC Class Container #"+this.$gc3Containers+"...",9);
		pc("F4 'Your FE Shipyards' to check your Licence.",9);
	} else
	// unmount & sell cancels all container additions
	if (equipment == "EQ_MISSILE_REMOVAL") {
		player.ship.cargoSpaceCapacity -= this.$gc3Containers*30;
		if (this.$gc3Containers>0) {
			pc("Removing all 30 TC Class Containers...",9);
			pc("Restoring pylon hardpoints for weapons-use...",9);
		}
		if ((this.$gc3Containers>0) && (!this.$gc3HFExempt)) {
			// dismantling fee
			var dft = this.$gc3Containers*this.$gc3DismantlingFee;
			this.$gc3DismantlingFeeTotal += dft;
			player.credits -= dft;
			pc("Dismantling Fee: "+dft+" cr",9);
		}
		this.$gc3Count = 0;
		this.$gc3Containers = 0;
		// reset system-to-system runs w/containers
		this.$gc3Runs = 0;
		// reset fee totals
		this.$gc3HandlingFeeTotal = 0;
		this.$gc3MaintenanceFeeTotal = 0;
	}
}


this.playerBoughtNewShip = function(ship, price) {
	// missile capacity (not exceed)
	this.$gc3MCap = player.ship.missileCapacity;
	this.$gc3Count = 0;
	this.$gc3Containers = 0;
}


this.equipmentRemoved = function(equipmentKey) {
    if (equipmentKey == "EQ_GC3_MINE") {
		player.ship.cargoSpaceCapacity -= 30;
		this.$gc3Containers--;	
		player.consoleMessage("30 TC Goods Container removed.",5);
	}
}


this.shipReleasedEquipment = function(mine) {
	this.$gc3Count--;
    if (mine == "EQ_GC3_MINE") {
		player.ship.cargoSpaceCapacity -= 30;
		this.$gc3Containers--;
		player.commsMessage("30 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 30000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.shipFiredMissile = function(missile, target) {
	this.$gc3Count--;
    if (missile == "EQ_GC3_MINE") {
		player.ship.cargoSpaceCapacity -= 30;
		this.$gc3Containers--;	
		player.commsMessage("30 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 30000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.startUpComplete = function () {
	var pc = player.consoleMessage;
	// missile capacity (not exceed)
	this.$gc3MCap = player.ship.missileCapacity;
	this.$gc3Count = player.ship.missiles.length;
	// Load cargo space, missile & container counts if present
	if (missionVariables.gc3Cargo != null) 
		player.ship.cargoSpaceCapacity = missionVariables.gc3Cargo;
	if (missionVariables.gc3Count != null)
		this.$gc3Count = missionVariables.gc3Count;
	if (missionVariables.gc3Containers != null) 
		this.$gc3Containers = missionVariables.gc3Containers;
	// Load total fees taken
	if (missionVariables.gc3HandlingFeeTotal != null)
		this.$gc3HandlingFeeTotal = missionVariables.gc3HandlingFeeTotal;
	if (missionVariables.gc3HandlingPaid != null)
		this.$gc3HandlingPaid = missionVariables.gc3HandlingPaid;
	if (missionVariables.gc3MaintenanceFeeTotal != null)
		this.$gc3MaintenanceFeeTotal = missionVariables.gc3MaintenanceFeeTotal;
	if (missionVariables.gc3DismantlingFeeTotal != null)
		this.$gc3DismantlingFeeTotal = missionVariables.gc3DismantlingFeeTotal; 
    // Load system-to-system runs w/container
	if (missionVariables.gc3Runs != null)
		this.$gc3Runs = missionVariables.gc3Runs;
	// Load Handling fee count
	if (missionVariables.gc3HandlingCount != null)
		this.$gc3HandlingCount = missionVariables.gc3HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.gc3HFExempt != null)
		this.$gc3HFExempt = missionVariables.gc3HFExempt;
	// Load Maintenance fee count
	if (missionVariables.gc3MaintenanceCount != null)
		this.$gc3MaintenanceCount = missionVariables.gc3MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// TEST
	var sta = player.ship.dockedStation;
	if ((this.$gc3Containers<this.$gc3MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	// prepare container Account screen
	if (this.$gc3Containers>0) this._gc3PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$gc3Containers>0) this._gc3PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$gc3ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$gc3ET = true;
	// TEST	
	if (this.$gc3ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$gc3FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$gc3FES = true;
	// TEST	
	if (this.$gc3ET) log(this.name, "Finds FE Ships Player present");
	// missile capacity (not exceed)
	this.$gc3MCap = 0;
	// pylon-use count
	this.$gc3Count = 0;
	// container count
	this.$gc3Containers = 0;
	// purchase cost of container in cr
	this.$gc3Cost = 30000;
	// handling fee
	this.$gc3HandlingFee = 0.005*this.$gc3Cost; // 0.005 of cost
	this.$gc3HandlingFeeTotal = 0;
	this.$gc3HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$gc3HandlingCount = 0;
	this.$gc3HFExempt = "no";
	// maintenance fee
	this.$gc3MaintenanceFee = 0.05*this.$gc3Cost; // 0.05 of cost
	this.$gc3MaintenanceFeeTotal = 0;
	this.$gc3MaintenancePaid = "no" // or "yes"
	this.$gc3MaintenanceInterval = 30; // in runs (according to cost)
	this.$gc3MaintenanceCount = 0;
	// dismantling fee
	this.$gc3DismantlingFee = 0.1*this.$gc3Cost; // 0.1 of cost
	this.$gc3DismantlingFeeTotal = 0.0;
	// system-to-system runs w/container
	this.$gc3Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.gc3Count = this.$gc3Count;
	missionVariables.gc3Cargo = player.ship.cargoSpaceCapacity;
	missionVariables.gc3Containers = this.$gc3Containers;
	// save total fees taken
	missionVariables.gc3HandlingFeeTotal = this.$gc3HandlingFeeTotal;
	missionVariables.gc3MaintenanceFeeTotal = this.$gc3MaintenanceFeeTotal;
	missionVariables.gc3DismantlingFeeTotal = this.$gc3DismantlingFeeTotal;
	missionVariables.gc3HandlingPaid = this.$gc3HandlingPaid;
	// system-to-system runs w/container
	missionVariables.gc3Runs =this.$gc3Runs;
	// handling fee count
	missionVariables.gc3HandlingCount = this.$gc3HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.gc3HFExempt = this.$gc3HFExempt;
	// maintenance fee count
	missionVariables.gc3MaintenanceCount = this.$gc3MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$gc3HFExempt;
	// check we have containers, the fee is not paid, and we're not exempt
	if ((this.$gc3Containers>0) && (this.$gc3HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$gc3Containers; x++)
			fee += this.$gc3HandlingFee;
		// record fee and debit trader's account
		this.$gc3HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$gc3HandlingPaid = "yes";
		pc("30 TC Container handling fees: "+fee+" cr",9);
		this.$gc3HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$gc3Containers>0) this._gc3DoMaintenance();

	// TEST
	if ((this.$gc3Containers<this.$gc3MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	
	// prepare container Account and Licence page
	if (this.$gc3Containers>0) this._gc3PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$gc3Containers>0) this._gc3PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$gc3HandlingPaid = "no";
	this.$gc3Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._gc3DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$gc3Runs;
	var intv = this.$gc3MaintenanceInterval;
	var mfee = this.$gc3MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x containers
		var fee = 0;
		for (var x=1; x<= this.$gc3Containers; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$gc3MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("30 TC Container Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$gc3MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._gc3PrepAcc = function(station) {
	station.setInterface("gc3Acc",{
	title: "Your FE Shipyards 30 TC Container Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 30 TC Goods Container account screen shows terms, fees paid, load, and other useful information.",
	callback: this._gc3ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._gc3ShowAcc = function() {
	var hfc = this.$gc3HandlingCount;
	var mfc = this.$gc3MaintenanceCount;
	var mfi = this.$gc3MaintenanceInterval;
	var hft = this.$gc3HandlingFeeTotal;
	var mft = this.$gc3MaintenanceFeeTotal;
	var dft = this.$gc3DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$gc3Containers>0) 
		parameters.message +="Your Account and Licence for 30 TC Class Goods Containers x "+this.$gc3Containers+": \n\n"; 
	 else
		parameters.message +="You have no 30 TC Class Containers licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our containers are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Container account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylons for weapons-use. \n";
	
	parameters.choicesKey = "gc3Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._gc3PrepEx = function(station) {
	station.setInterface("gc3Ex",{
	title: "Your FE Shipyards Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 30-ton container class." ,
	callback: this._gc3ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._gc3ShowEx = function() {
	var priv = ((this.$gc3ET)||(this.$gc3FES));
	var privo = "";
	if (this.$gc3FES) privo="FE shipowner";
	if (this.$gc3ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 30 TC container fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "gc3YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$gc3HFExempt = "yes"; else this.$gc3HFExempt = "no";
		} else this.$gc3HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}



Scripts/gc4_script.js
"use strict";
this.name = "Goods Container 40 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "2.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	// keep tally of pylon accessories bought
	this.$gc4Count++;
    // and don't let them exceed ship's pylon-capacity
	if ((equipment == "EQ_GC4_MINE") && (this.$gc4Count<=this.$gc4MCap)) {
		player.ship.cargoSpaceCapacity += 40;
		this.$gc4Containers++;
		pc("Modifying pylon hardpoints for container clamping...",9);
		pc("Fitting 40 TC Class Container #"+this.$gc4Containers+"...",9);
		pc("F4 'Your FE Shipyards' to check your Licence.",9);
	} else
	// unmount & sell cancels all container additions
	if (equipment == "EQ_MISSILE_REMOVAL") {
		player.ship.cargoSpaceCapacity -= this.$gc4Containers*40;
		if (this.$gc4Containers>0) {
			pc("Removing all 40 TC Class Containers...",9);
			pc("Restoring pylon hardpoints for weapons-use...",9);
		}
		if ((this.$gc4Containers>0) && (!this.$gc4HFExempt)) {
			// dismantling fee
			var dft = this.$gc4Containers*this.$gc4DismantlingFee;
			this.$gc4DismantlingFeeTotal += dft;
			player.credits -= dft;
			pc("Dismantling Fee: "+dft+" cr",9);
		}
		this.$gc4Count = 0;
		this.$gc4Containers = 0;
		// reset system-to-system runs w/containers
		this.$gc4Runs = 0;
		// reset fee totals
		this.$gc4HandlingFeeTotal = 0;
		this.$gc4MaintenanceFeeTotal = 0;
	}
}


this.playerBoughtNewShip = function(ship, price) {
	// missile capacity (not exceed)
	this.$gc4MCap = player.ship.missileCapacity;
	this.$gc4Count = 0;
	this.$gc4Containers = 0;
}


this.equipmentRemoved = function(equipmentKey) {
    if (equipmentKey == "EQ_GC4_MINE") {
		player.ship.cargoSpaceCapacity -= 40;
		this.$gc4Containers--;	
		player.consoleMessage("40 TC Goods Container removed.",5);
	}
}


this.shipReleasedEquipment = function(mine) {
	this.$gc4Count--;
    if (mine == "EQ_GC4_MINE") {
		player.ship.cargoSpaceCapacity -= 40;
		this.$gc4Containers--;
		player.commsMessage("40 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 40000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.shipFiredMissile = function(missile, target) {
	this.$gc4Count--;
    if (missile == "EQ_GC4_MINE") {
		player.ship.cargoSpaceCapacity -= 40;
		this.$gc4Containers--;	
		player.commsMessage("40 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 40000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.startUpComplete = function () {
	var pc = player.consoleMessage;
	// missile capacity (not exceed)
	this.$gc4MCap = player.ship.missileCapacity;
	this.$gc4Count = player.ship.missiles.length;
	// Load cargo space, missile & container counts if present
	if (missionVariables.gc4Cargo != null) 
		player.ship.cargoSpaceCapacity = missionVariables.gc4Cargo;
	if (missionVariables.gc4Count != null)
		this.$gc4Count = missionVariables.gc4Count;
	if (missionVariables.gc4Containers != null) 
		this.$gc4Containers = missionVariables.gc4Containers;
	// Load total fees taken
	if (missionVariables.gc4HandlingFeeTotal != null)
		this.$gc4HandlingFeeTotal = missionVariables.gc4HandlingFeeTotal;
	if (missionVariables.gc4HandlingPaid != null)
		this.$gc4HandlingPaid = missionVariables.gc4HandlingPaid;
	if (missionVariables.gc4MaintenanceFeeTotal != null)
		this.$gc4MaintenanceFeeTotal = missionVariables.gc4MaintenanceFeeTotal;
	if (missionVariables.gc4DismantlingFeeTotal != null)
		this.$gc4DismantlingFeeTotal = missionVariables.gc4DismantlingFeeTotal; 
    // Load system-to-system runs w/container
	if (missionVariables.gc4Runs != null)
		this.$gc4Runs = missionVariables.gc4Runs;
	// Load Handling fee count
	if (missionVariables.gc4HandlingCount != null)
		this.$gc4HandlingCount = missionVariables.gc4HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.gc4HFExempt != null)
		this.$gc4HFExempt = missionVariables.gc4HFExempt;
	// Load Maintenance fee count
	if (missionVariables.gc4MaintenanceCount != null)
		this.$gc4MaintenanceCount = missionVariables.gc4MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// TEST
	var sta = player.ship.dockedStation;
	if ((this.$gc4Containers<this.$gc4MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	// prepare container Account screen
	if (this.$gc4Containers>0) this._gc4PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$gc4Containers>0) this._gc4PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$gc4ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$gc4ET = true;
	// TEST	
	if (this.$gc4ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$gc4FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$gc4FES = true;
	// TEST	
	if (this.$gc4ET) log(this.name, "Finds FE Ships Player present");
	// missile capacity (not exceed)
	this.$gc4MCap = 0;
	// pylon-use count
	this.$gc4Count = 0;
	// container count
	this.$gc4Containers = 0;
	// purchase cost of container in cr
	this.$gc4Cost = 40000;
	// handling fee
	this.$gc4HandlingFee = 0.005*this.$gc4Cost; // 0.005 of cost
	this.$gc4HandlingFeeTotal = 0;
	this.$gc4HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$gc4HandlingCount = 0;
	this.$gc4HFExempt = "no";
	// maintenance fee
	this.$gc4MaintenanceFee = 0.05*this.$gc4Cost; // 0.05 of cost
	this.$gc4MaintenanceFeeTotal = 0;
	this.$gc4MaintenancePaid = "no" // or "yes"
	this.$gc4MaintenanceInterval = 40; // in runs (according to cost)
	this.$gc4MaintenanceCount = 0;
	// dismantling fee
	this.$gc4DismantlingFee = 0.1*this.$gc4Cost; // 0.1 of cost
	this.$gc4DismantlingFeeTotal = 0.0;
	// system-to-system runs w/container
	this.$gc4Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.gc4Count = this.$gc4Count;
	missionVariables.gc4Cargo = player.ship.cargoSpaceCapacity;
	missionVariables.gc4Containers = this.$gc4Containers;
	// save total fees taken
	missionVariables.gc4HandlingFeeTotal = this.$gc4HandlingFeeTotal;
	missionVariables.gc4MaintenanceFeeTotal = this.$gc4MaintenanceFeeTotal;
	missionVariables.gc4DismantlingFeeTotal = this.$gc4DismantlingFeeTotal;
	missionVariables.gc4HandlingPaid = this.$gc4HandlingPaid;
	// system-to-system runs w/container
	missionVariables.gc4Runs =this.$gc4Runs;
	// handling fee count
	missionVariables.gc4HandlingCount = this.$gc4HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.gc4HFExempt = this.$gc4HFExempt;
	// maintenance fee count
	missionVariables.gc4MaintenanceCount = this.$gc4MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$gc4HFExempt;
	// check we have containers, the fee is not paid, and we're not exempt
	if ((this.$gc4Containers>0) && (this.$gc4HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$gc4Containers; x++)
			fee += this.$gc4HandlingFee;
		// record fee and debit trader's account
		this.$gc4HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$gc4HandlingPaid = "yes";
		pc("40 TC Container handling fees: "+fee+" cr",9);
		this.$gc4HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$gc4Containers>0) this._gc4DoMaintenance();

	// TEST
	if ((this.$gc4Containers<this.$gc4MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	
	// prepare container Account and Licence page
	if (this.$gc4Containers>0) this._gc4PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$gc4Containers>0) this._gc4PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$gc4HandlingPaid = "no";
	this.$gc4Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._gc4DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$gc4Runs;
	var intv = this.$gc4MaintenanceInterval;
	var mfee = this.$gc4MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x containers
		var fee = 0;
		for (var x=1; x<= this.$gc4Containers; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$gc4MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("40 TC Container Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$gc4MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._gc4PrepAcc = function(station) {
	station.setInterface("gc4Acc",{
	title: "Your FE Shipyards 40 TC Container Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 40 TC Goods Container account screen shows terms, fees paid, load, and other useful information.",
	callback: this._gc4ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._gc4ShowAcc = function() {
	var hfc = this.$gc4HandlingCount;
	var mfc = this.$gc4MaintenanceCount;
	var mfi = this.$gc4MaintenanceInterval;
	var hft = this.$gc4HandlingFeeTotal;
	var mft = this.$gc4MaintenanceFeeTotal;
	var dft = this.$gc4DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$gc4Containers>0) 
		parameters.message +="Your Account and Licence for 40 TC Class Goods Containers x "+this.$gc4Containers+": \n\n"; 
	 else
		parameters.message +="You have no 40 TC Class Containers licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our containers are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Container account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylons for weapons-use. \n";
	
	parameters.choicesKey = "gc4Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._gc4PrepEx = function(station) {
	station.setInterface("gc4Ex",{
	title: "Your FE Shipyards Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 40-ton container class." ,
	callback: this._gc4ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._gc4ShowEx = function() {
	var priv = ((this.$gc4ET)||(this.$gc4FES));
	var privo = "";
	if (this.$gc4FES) privo="FE shipowner";
	if (this.$gc4ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 40 TC container fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "gc4YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$gc4HFExempt = "yes"; else this.$gc4HFExempt = "no";
		} else this.$gc4HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}



Scripts/gc5_script.js
"use strict";
this.name = "Goods Container 50 TC";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "2.0";


this.playerBoughtEquipment = function(equipment, paid) {
	var pc = player.consoleMessage;
	// keep tally of pylon accessories bought
	this.$gc5Count++;
    // and don't let them exceed ship's pylon-capacity
	if ((equipment == "EQ_GC5_MINE") && (this.$gc5Count<=this.$gc5MCap)) {
		player.ship.cargoSpaceCapacity += 50;
		this.$gc5Containers++;
		pc("Modifying pylon hardpoints for container clamping...",9);
		pc("Fitting 50 TC Class Container #"+this.$gc5Containers+"...",9);
		pc("F4 'Your FE Shipyards' to check your Licence.",9);
	} else
	// unmount & sell cancels all container additions
	if (equipment == "EQ_MISSILE_REMOVAL") {
		player.ship.cargoSpaceCapacity -= this.$gc5Containers*50;
		if (this.$gc5Containers>0) {
			pc("Removing all 50 TC Class Containers...",9);
			pc("Restoring pylon hardpoints for weapons-use...",9);
		}
		if ((this.$gc5Containers>0) && (!this.$gc5HFExempt)) {
			// dismantling fee
			var dft = this.$gc5Containers*this.$gc5DismantlingFee;
			this.$gc5DismantlingFeeTotal += dft;
			player.credits -= dft;
			pc("Dismantling Fee: "+dft+" cr",9);
		}
		this.$gc5Count = 0;
		this.$gc5Containers = 0;
		// reset system-to-system runs w/containers
		this.$gc5Runs = 0;
		// reset fee totals
		this.$gc5HandlingFeeTotal = 0;
		this.$gc5MaintenanceFeeTotal = 0;
	}
}


this.playerBoughtNewShip = function(ship, price) {
	// missile capacity (not exceed)
	this.$gc5MCap = player.ship.missileCapacity;
	this.$gc5Count = 0;
	this.$gc5Containers = 0;
}


this.equipmentRemoved = function(equipmentKey) {
    if (equipmentKey == "EQ_GC5_MINE") {
		player.ship.cargoSpaceCapacity -= 50;
		this.$gc5Containers--;	
		player.consoleMessage("50 TC Goods Container removed.",5);
	}
}


this.shipReleasedEquipment = function(mine) {
	this.$gc5Count--;
    if (mine == "EQ_GC5_MINE") {
		player.ship.cargoSpaceCapacity -= 50;
		this.$gc5Containers--;
		player.commsMessage("50 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 50000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.shipFiredMissile = function(missile, target) {
	this.$gc5Count--;
    if (missile == "EQ_GC5_MINE") {
		player.ship.cargoSpaceCapacity -= 50;
		this.$gc5Containers--;	
		player.commsMessage("50 TC Goods Container jettisoned.",5);
		// deduct container cost from credits
		player.credits -= 50000.0;
		player.commsMessage("Mishandling charge applied at cost.",9);
	}
}


this.startUpComplete = function () {
	var pc = player.consoleMessage;
	// missile capacity (not exceed)
	this.$gc5MCap = player.ship.missileCapacity;
	this.$gc5Count = player.ship.missiles.length;
	// Load cargo space, missile & container counts if present
	if (missionVariables.gc5Cargo != null) 
		player.ship.cargoSpaceCapacity = missionVariables.gc5Cargo;
	if (missionVariables.gc5Count != null)
		this.$gc5Count = missionVariables.gc5Count;
	if (missionVariables.gc5Containers != null) 
		this.$gc5Containers = missionVariables.gc5Containers;
	// Load total fees taken
	if (missionVariables.gc5HandlingFeeTotal != null)
		this.$gc5HandlingFeeTotal = missionVariables.gc5HandlingFeeTotal;
	if (missionVariables.gc5HandlingPaid != null)
		this.$gc5HandlingPaid = missionVariables.gc5HandlingPaid;
	if (missionVariables.gc5MaintenanceFeeTotal != null)
		this.$gc5MaintenanceFeeTotal = missionVariables.gc5MaintenanceFeeTotal;
	if (missionVariables.gc5DismantlingFeeTotal != null)
		this.$gc5DismantlingFeeTotal = missionVariables.gc5DismantlingFeeTotal; 
    // Load system-to-system runs w/container
	if (missionVariables.gc5Runs != null)
		this.$gc5Runs = missionVariables.gc5Runs;
	// Load Handling fee count
	if (missionVariables.gc5HandlingCount != null)
		this.$gc5HandlingCount = missionVariables.gc5HandlingCount;
	// Load handling fee exemption status
	if (missionVariables.gc5HFExempt != null)
		this.$gc5HFExempt = missionVariables.gc5HFExempt;
	// Load Maintenance fee count
	if (missionVariables.gc5MaintenanceCount != null)
		this.$gc5MaintenanceCount = missionVariables.gc5MaintenanceCount;
	// CHECK
	log(this.name, this.name+" startup complete.");
	// TEST
	var sta = player.ship.dockedStation;
	if ((this.$gc5Containers<this.$gc5MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	// prepare container Account screen
	if (this.$gc5Containers>0) this._gc5PrepAcc(sta);
	// optionally, prepare handling fee waiver request
	if (this.$gc5Containers>0) this._gc5PrepEx(sta);
}


this.startUp = function() {
    log(this.name, "Initialising OXP " + this.name);
	// check for G.E.T. presence
	this.$gc5ET = false;
	if (worldScripts["Elite Trader"]) 
		this.$gc5ET = true;
	// TEST	
	if (this.$gc5ET) log(this.name, "Finds Elite Trader present");
	// check for FE Ships Player
	this.$gc5FES = false;
	if (worldScripts["FE Ships Player"]) 
		this.$gc5FES = true;
	// TEST	
	if (this.$gc5ET) log(this.name, "Finds FE Ships Player present");
	// missile capacity (not exceed)
	this.$gc5MCap = 0;
	// pylon-use count
	this.$gc5Count = 0;
	// container count
	this.$gc5Containers = 0;
	// purchase cost of container in cr
	this.$gc5Cost = 50000;
	// handling fee
	this.$gc5HandlingFee = 0.005*this.$gc5Cost; // 0.005 of cost
	this.$gc5HandlingFeeTotal = 0;
	this.$gc5HandlingPaid = "yes"; // or "no" - easier than boolean
	this.$gc5HandlingCount = 0;
	this.$gc5HFExempt = "no";
	// maintenance fee
	this.$gc5MaintenanceFee = 0.05*this.$gc5Cost; // 0.05 of cost
	this.$gc5MaintenanceFeeTotal = 0;
	this.$gc5MaintenancePaid = "no" // or "yes"
	this.$gc5MaintenanceInterval = 50; // in runs (according to cost)
	this.$gc5MaintenanceCount = 0;
	// dismantling fee
	this.$gc5DismantlingFee = 0.1*this.$gc5Cost; // 0.1 of cost
	this.$gc5DismantlingFeeTotal = 0.0;
	// system-to-system runs w/container
	this.$gc5Runs = 0;
}


this.playerWillSaveGame = function(message) {
	missionVariables.gc5Count = this.$gc5Count;
	missionVariables.gc5Cargo = player.ship.cargoSpaceCapacity;
	missionVariables.gc5Containers = this.$gc5Containers;
	// save total fees taken
	missionVariables.gc5HandlingFeeTotal = this.$gc5HandlingFeeTotal;
	missionVariables.gc5MaintenanceFeeTotal = this.$gc5MaintenanceFeeTotal;
	missionVariables.gc5DismantlingFeeTotal = this.$gc5DismantlingFeeTotal;
	missionVariables.gc5HandlingPaid = this.$gc5HandlingPaid;
	// system-to-system runs w/container
	missionVariables.gc5Runs =this.$gc5Runs;
	// handling fee count
	missionVariables.gc5HandlingCount = this.$gc5HandlingCount;
	// handling fee exemption (G.E.T.)
	missionVariables.gc5HFExempt = this.$gc5HFExempt;
	// maintenance fee count
	missionVariables.gc5MaintenanceCount = this.$gc5MaintenanceCount;
}


this.shipDockedWithStation = function(station) {
	// take handling fee (if not exempt)
	var pc = player.consoleMessage;
	var ex = this.$gc5HFExempt;
	// check we have containers, the fee is not paid, and we're not exempt
	if ((this.$gc5Containers>0) && (this.$gc5HandlingPaid==="no") && (ex==="no")) {
		var fee = 0;
		for (var x=1; x<= this.$gc5Containers; x++)
			fee += this.$gc5HandlingFee;
		// record fee and debit trader's account
		this.$gc5HandlingFeeTotal += fee;
		player.credits -= fee;
		this.$gc5HandlingPaid = "yes";
		pc("50 TC Container handling fees: "+fee+" cr",9);
		this.$gc5HandlingCount++;
	}

	// conditionally take maintenance fee
	if (this.$gc5Containers>0) this._gc5DoMaintenance();

	// TEST
	if ((this.$gc5Containers<this.$gc5MCap) && (system.techLevel>=6))
		pc("Containers available in the Shipyard.");
	
	// prepare container Account and Licence page
	if (this.$gc5Containers>0) this._gc5PrepAcc(station);
	
	// prepare handling fee waiver request if ET or FESP is present
	if (this.$gc5Containers>0) this._gc5PrepEx(station);
}



this.shipExitedWitchspace = function() {
	// set handling paid to 'no'
	this.$gc5HandlingPaid = "no";
	this.$gc5Runs ++;
}


/* Common helper functions */


// assess and take maintenance fee
this._gc5DoMaintenance = function() {
	var pc = player.consoleMessage;
	var runs = this.$gc5Runs;
	var intv = this.$gc5MaintenanceInterval;
	var mfee = this.$gc5MaintenanceFee;
	// take maintenance fee after y runs
	if ( (runs > 0) && ((runs % intv)==0) ) {
		// maintenance for x containers
		var fee = 0;
		for (var x=1; x<= this.$gc5Containers; x++)
			fee += mfee;
		// maintenance fee tally & debit
		this.$gc5MaintenanceFeeTotal += fee;
		player.credits -= fee;
		pc("50 TC Container Maintenance fees: "+fee+" cr",9);
		// update Maintenance count
		this.$gc5MaintenanceCount++;
	}
}


/* F4 Interfaces */


// create F.E.S. 'Licence & Account' page 
this._gc5PrepAcc = function(station) {
	station.setInterface("gc5Acc",{
	title: "Your FE Shipyards 50 TC Container Class Licence",
	category: "Your FE Shipyards",
	summary: "Your FE Shipyards 50 TC Goods Container account screen shows terms, fees paid, load, and other useful information.",
	callback: this._gc5ShowAcc.bind(this)
	});	
}


// show F.E.S. 'Licence & Account' page
this._gc5ShowAcc = function() {
	var hfc = this.$gc5HandlingCount;
	var mfc = this.$gc5MaintenanceCount;
	var mfi = this.$gc5MaintenanceInterval;
	var hft = this.$gc5HandlingFeeTotal;
	var mft = this.$gc5MaintenanceFeeTotal;
	var dft = this.$gc5DismantlingFeeTotal;
		
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	if (this.$gc5Containers>0) 
		parameters.message +="Your Account and Licence for 50 TC Class Goods Containers x "+this.$gc5Containers+": \n\n"; 
	 else
		parameters.message +="You have no 50 TC Class Containers licensed with us at this time. \n\n";
	
	parameters.message +="Handling fees paid: "+hft+" cr ("+hfc+") \n";
	parameters.message +="Maintenance fees paid: "+mft+" cr ("+mfc+") \n";
	parameters.message +="Dismantling fees paid: "+dft+" cr \n\n";
	
	parameters.message += "Our containers are re-used many times per cycle, often many times per day. Maintaining them in clean and serviceable condition for their maximum useful lifetime is our prime concern at FE Shipyards, and we trust that you, our valued customer, understand the need for your own participation in this costly and ongoing process. \n\n";
	
	parameters.message += "The handling charge (0.005 of cost) is levied upon docking, the maintenance fee (0.05 of cost) every "+mfi+" system-to-system trading runs. \n\n"
	
	parameters.message += "If you cancel your Container account with us at any time, we must charge the dismantling fee (0.1 of cost) to re-modify and restore your vessel's pylons for weapons-use. \n";
	
	parameters.choicesKey = "gc5Acknowlege";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_YES")  player.commsMessage("FE Shipyards thanks you for your custom.");
	}
}



// create F.E.S. handling fee waiver/restoration request  
this._gc5PrepEx = function(station) {
	station.setInterface("gc5Ex",{
	title: "Your FE Shipyards Handling Fee Waiver Request",
	category: "Your FE Shipyards",
	summary: "FE Shipyards grants Guilders and FE shipowners the privileged option to waive our handling and dismantling fees for the 50-ton container class." ,
	callback: this._gc5ShowEx.bind(this)
	});	
}


// show F.E.S. handling & dismantling fee waiver/restoration request
this._gc5ShowEx = function() {
	var priv = ((this.$gc5ET)||(this.$gc5FES));
	var privo = "";
	if (this.$gc5FES) privo="FE shipowner";
	if (this.$gc5ET) privo="Guilder";
	
	var parameters = new Object();
	
	parameters.title = "FE Shipyards";
	
	parameters.message = "Dear customer, \n\n";
	
	parameters.message += "Re: your request to waive your 50 TC container fees.\n\n"
	
	parameters.message += "The handling fee (0.005 of cost) is taken from your account upon docking, and is merely to cover our attachment/detachment & loading/unloading services. The dismantling fee (0.1 of cost) is charged when re-modifying your pylons for weapons-use after Licence cancellation. \n\n";
	
	if (priv)
		parameters.message += "FE Shipyards grants you, as a "+privo+", the privileged option to waive our handling and dismantling fees, although you are free - and encouraged - to continue supporting our efforts to provide the efficient service you as an Elite Trader deserve. \n\n";
	else
		parameters.message += "FE Shipyards regrets that we are unable at this time to grant you an exemption from fees, which is a privilege of Guilders and FE shipowners exclusively. \n\n";
	
	parameters.message += "Yours attentively,\n\n";
	
	parameters.message += "Siri Chodrum, for Dor Reval (Technical Director)\n";
	

	parameters.choicesKey = "gc5YesNoEx";
	
	mission.runScreen(parameters, callback);	

	function callback(choice) {
		if (choice === "1_AYE")  {
			if (priv) this.$gc5HFExempt = "yes"; else this.$gc5HFExempt = "no";
		} else this.$gc5HFExempt = "no";
		player.commsMessage("FE Shipyards thanks you for your attention.");
	}	
}



Scripts/gc_conditions.js
"use strict";

this.allowAwardEquipment = function(equipment, ship, context) {
	return true
}
Scripts/gh_script.js
"use strict";
this.name = "GETter HUD";
this.author = "Reval";
this.licence = "CC BY-NC-SA 4.0";
this.version = "1.3";


this.startUpComplete = function() {
	this._ghlistGoods();
	this._ghlistOwner();
	this._ghlistCap();
}


this.playerBoughtNewShip = function(ship, price) {
	this._ghlistGoods();
	this._ghlistOwner();
	this._ghlistCap();
}


this.playerBoughtEquipment = function(equipment, paid) {
	this._ghlistGoods();
	this._ghlistOwner();
	this._ghlistCap();
}


this.equipmentAdded = function(equipmentKey) {
	this._ghlistGoods();
	this._ghlistOwner();
	this._ghlistCap();
}


this.shipWillLaunchFromStation = function() {
	if(!this.$Timer) this.$Timer = new Timer(this,this._ghupdateSpeed.bind(this),0,0.25);
	if(!this.$Timer1) this.$Timer1 = new Timer(this,this._ghshowWeps.bind(this),0,0.25);
	this._ghlistGoods();
	this._ghlistOwner();
	this._ghlistCap();
}


this.guiScreenChanged = function(to, from) {
	if ((from=="GUI_SCREEN_MARKET")||(from=="GUI_SCREEN_MANIFEST")) {
		this._ghlistGoods();
		this._ghlistOwner();
		this._ghlistCap();
	}
}


this._ghcenteredText = function(txt, width) {
	var t = ""+txt; // force to string, else txt.length is undefined for numbers
	var w = width / 2;
	while( t && t.length < w ) { // for fixed width font in setCustomHUDDial
		t = " " + t;
	}
	return(t);
}


this._ghupdateSpeed = function () {
	var p = player.ship;
	if((!p) || (!p.isValid)) return; // player died

	var setd = p.setCustomHUDDial;
	if (setd) {
		var sp = p.speed;
		sp = this._ghcenteredText(sp.toFixed(1), 28); // default width
		setd("shipSpeed", sp);
	}
}


// output capList to HUD
this._ghlistCap = function() {
	var p = player.ship;
	if((!p) || (!p.isValid)) return; // player died

	var setd = p.setCustomHUDDial;
	if (setd) {
		var cap = this._ghcapList();
		setd("capList", cap);
	}
}


// show ship's TC capacity
this._ghcapList = function() {
	var result = "";
	result += "Capacity: ";
	result += player.ship.cargoSpaceCapacity+" TC";
	return result;
}


// output ownerList to HUD
this._ghlistOwner = function() {
	var p = player.ship;
	if((!p) || (!p.isValid)) return; // player died

	var setd = p.setCustomHUDDial;
	if (setd) {
		var owner = this._ghownerList();
		setd("ownerList", owner);
	}
}


// show ship, class, name, owner
this._ghownerList = function() {
	var result = "";
	result += "Cdr. ";
	result += player.name + ", ";
	result += player.ship.displayName;
	return result;
}


// output goods list to HUD
this._ghlistGoods = function() {
	var p = player.ship;
	if((!p) || (!p.isValid)) return; // player died

	var setd = p.setCustomHUDDial;
	if (setd) {
		var goods = this._ghgoodsList();
		setd("goodsList", goods);
	}
}


// list commodities in ship's hold
this._ghgoodsList = function() {
	var result = "";
	var m = manifest.list;
	for (var i=0; i<m.length; i++) {
		var q = m[i].commodity;
		if (q) result += q + " ("+m[i].quantity+")  ";
	}	
	if (result=="") result = "EMPTY";
	return result;
}


// weapons online indicator
this._ghshowWeps = function() {
	var p = player.ship;
	if((!p) || (!p.isValid)) return; // player died

	var setd = p.setCustomHUDDial;
	if (setd) {
		var weps = "";
		if (p.weaponsOnline) weps="W";
		setd("showWeapons", weps);
	}
}


Scripts/gl_market.js
"use strict";

this.name = "gl-market";
this.author = "Reval";

/* Thanks to Spara for producing this code! */
this.updateLocalCommodityDefinition = function(goodDefinition, station) {

	var distance = station.position.distanceTo(system.mainStation);
	
	//scale max price difference with distance
	//1000 km -> 0.05, 5000 km -> 0.15
	var maxPriceDiff = 0.000000025 * distance + 0.025;
	var priceDiff = Math.random() * maxPriceDiff;
	
	//cheaper or more expensive?
	var coinToss = Math.round(Math.random());
	if (coinToss === 0)  var priceMultiplier = 1 - priceDiff;
	else var priceMultiplier = 1 + priceDiff;
	
	goodDefinition.price *= priceMultiplier;
	
	//scale quantity with random +/- 100 % scale
	
	var quantityDiff = Math.random();
	var coinToss = Math.round(Math.random());
	if (coinToss === 0) var quantityMultiplier = 1 - quantityDiff;
	else var quantityMultiplier = 1 + quantityDiff;
	
	goodDefinition.quantity = Math.round(quantityMultiplier * goodDefinition.quantity);

	return goodDefinition;
};