Back to Index Page generated: Nov 12, 2024, 11:02:04 PM

Expansion Bank of the Black Monks

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Bank of the Black Monks invites you to undertake a short term financial pilgrimage for the Black Monks of St. Herod. In addition monasteries, that can be found in safe and advanced systems, sell blessed Holy Fuel. Beware of the Black Monk Gunships that persecute defaulters. Bank of the Black Monks invites you to undertake a short term financial pilgrimage for the Black Monks of St. Herod. In addition monasteries, that can be found in safe and advanced systems, sell blessed Holy Fuel. Beware of the Black Monk Gunships that persecute defaulters.
Identifier oolite.oxp.littlebear.blackmonks oolite.oxp.littlebear.blackmonks
Title Bank of the Black Monks Bank of the Black Monks
Category Activities Activities
Author LittleBear, Griff, spara LittleBear, Griff, spara
Version 2.2.1 2.2.1
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/Black_Monk_Monastery n/a
Download URL https://wiki.alioth.net/img_auth.php/a/a6/Blackmonks_2.2.1.oxz n/a
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1610873403

Documentation

Also read http://wiki.alioth.net/index.php/Bank%20of%20the%20Black%20Monks

readme.txt

			      Bank of the Black Monks OXP - V2.2.1
			     ------------------------------------

* Original concept (v1.x), reconcepting and flavor texts by "LittleBear"
* Reconcepting and scripting by "spara"
* Models, textures and shaders by "Griff"

------------------------------------------------------------------------------------------------

An addon for Oolite by Giles Williams.

Based on "Elite" by Ian Bell and David Braben.

Update history
---------------
Version 2.2.1 - A missing semicolon added to the shipdata.
Version 2.2 - Texts reproofread and aged by Diziet Sma. A new one shot welcome page shown when entering a monastery for the first time. New names for Defence Ships. Renamed gunship to be "Holy Avenger Mark II" and defence ship to be "Holy Defender Mark I".
Version 2.1.1 - Texts proofread and corrected by Cody.
Version 2.1 - screenIDs idded to the mission screens for compatibility with other OXPs. Monk image added as an overlay instead of background picture. New bigger monk image. Bug fixes.
Version 2.0 - A full rewrite and reconcepting of the OXP. (25.6.2015)

Version 1.46 - Corrected typo in equipment.plist
Version 1.45 - Corrected another typo in equipment.plist
version 1.44 - Added copy of minesweeperAI from Randon Hits oxp to remove the dependancy on that OXP being installed
Version 1.43 - Lengthened the dock object to workaround defence ship calmness - they now get angry faster :)
Version 1.42 - fixed incorrect weapon rage & energy stats on one of the defence ship turrets
Version 1.41 - removed bounty setting from defence ship, set scan_class to Neutral. Increased defence ship toughness stats
Version 1.4 - added Blackmonk Station Defence Ship
Version 1.3 - fixed the wrong shader vertex applied to station turrets 
Version 1.2 - um, can't remember the changes
Version 1.12 - Updated shaders slightly to avoid ATI missing texture bug. Added Materials so some shader effects work for on computers unable to run shaders
Version 1.1 - 27th January 2007. 


-------------------------------------------------------------------------------------------------

Added:-
-------

- Vast Black Monk Monasterys appear in safe high tech Systems.
- Players can to undertake a short term financial pilgrimage for the Black Monks.
- The dreaded Black Monk Gunships can be seen shooting down NPC debtors who failed to pay up.
- Players who fail to repay on time will also find themselves in a Gunship's sights!
- Holy Fuel buyable from the Monasteries.

LittleBear, Griff & spara

Equipment

Name Visible Cost [deci-credits] Tech-Level
Holy Fuel yes 800 1+

Ships

Name
Blackmonk Station Defence
Blackmonk Station Defence
Holy Defender Mark I
Blackmonk Station Defence
Holy Avenger Mark II
Blackmonk Gunship
Blackmonk Gunship
Blackmonk Gunship
Mine Sweeper Satellite Radar Dish
Mine Sweeper Satellite
Black Monk Monastery
Docking Bay
Blackmonk Monastery
Turret

Models

This expansion declares no models.

Scripts

Path
Scripts/blackmonk_conditions.js
"use strict";

this.name           =    "blackmonk_conditions";

this.allowAwardEquipment = function(eqKey, ship, context) {
	if (!player.ship.dockedStation.hasRole("blackmonk_monastery"))
		return false;
	return true;
}
Scripts/blackmonk_defence.js
"use strict";

this.name           = "blackmonk_defence";
this.description    = "defence script to name the ship";

this.shipSpawned = function() {
	ship.shipUniqueName = expandDescription("[monk-defence-ship-name]");
}
Scripts/blackmonk_fuel.js
"use strict";

this.name               = "blackmonk_fuel";

this.startUp = function() {
	this.$fillSound = new SoundSource;
	this.$fillSound.sound = "blackmonk_fill.ogg";
	if (missionVariables.blackmonk_fuel) {
		this.$condensedFuel = missionVariables.blackmonk_fuel;
	} else this.$condensedFuel = 0;
}

this.playerWillSaveGame = function() {
	missionVariables.blackmonk_fuel = this.$condensedFuel;
}

this.playerBoughtEquipment = function(equipment) {
	if (equipment === "EQ_HOLY_FUEL") {
		player.ship.removeEquipment(equipment);
		player.ship.fuel = 7;
		this.$condensedFuel = 10.5;//1.5*7 = 10.5
	}
	else if (equipment === "EQ_FUEL") this.$condensedFuel = 0;
}

this.shipWillLaunchFromStation = function() {
	if (this.$condensedFuel > 7) {
		this.$fuelMonitor = new Timer(this, this._fuelMonitor, 0, 1);
	}
}

this.shipWillDockWithStation = function() {
	if (this.$fuelMonitor) {
		this.$fuelMonitor.stop();
		delete this.$fuelMonitor;
	}
}

this._fuelMonitor = function() {
	if (player.ship.fuel < 7 && this.$condensedFuel > player.ship.fuel && !this.$fuelAnimation) {
		this.$fuelAnimation = addFrameCallback(this._fuelAnimation.bind(this));
	}
}

this._fuelAnimation = function() {
	if (player.ship.fuel < 7 && this.$condensedFuel > player.ship.fuel) {
		player.ship.fuel += 0.1;
		this.$condensedFuel -= 0.1;
		if (!this.$fillSound.isPlaying) this.$fillSound.play();
	}
	else {
		removeFrameCallback(this.$fuelAnimation);
		delete this.$fuelAnimation;
		//all gone?
		if (player.ship.fuel < 7) {
			this.$condensedFuel = 0;
			this.$fuelMonitor.stop();
			delete this.$fuelMonitor;
		}
	}
}

Scripts/blackmonk_gunship.js
"use strict";

this.name           = "blackmonk_gunship";
this.description    = "gunship script to trigger debtor pleas and name the ship";

this.shipAttackedOther = function(other){
	if (other.$monkDebtor && Math.random() < 0.1) {
		other.commsMessage("[debtor-plea]");
	}
}

this.shipSpawned = function() {
	ship.shipUniqueName = expandDescription("[monk-ships]");
}
Scripts/blackmonk_main.js
//17.7.2015 -spara-

"use strict";

this.name               = "blackmonks";
this.author				= "spara";
this.description		= "Main script for Black Monks";

this.startUp = function() {
	if (missionVariables.blackmonk_contract) {
		this.$contract = JSON.parse(missionVariables.blackmonk_contract);
		delete missionVariables.blackmonk_contract;
	}
	this._setMonkSystems();
	//control payback on docking
	this.$offerOnce = false;
	//control one shot welcome screen
	if (!missionVariables.blackmonk_intro) this.$monkIntro = true;
	else this.$monkIntro = false;
}

this.playerEnteredNewGalaxy = function() {
	this._setMonkSystems();
}

//make a list of suitable monk systems
this._setMonkSystems = function() {
	this.$monkSystems = new Array();
	this.$monkSystemIDs = new Array();
	
	//first we'll utilize the basic rules
	var systems = SystemInfo.filteredSystems(this, function(other) {
		if (other.government >= 6 && other.techlevel >= 11 && !other.sun_gone_nova) {
			return (other);
		}
	});
	
	//only systems that are connected to others so that missions work are accepted
	for (var i = 0; i < systems.length; i++) {
		var destinations = 0;
		for (var j = 0; j < systems.length; j++) {
			var routeInfo = System.infoForSystem(galaxyNumber, systems[i].systemID).routeToSystem(systems[j]);
			if (routeInfo && routeInfo.route.length > 9) destinations++;
		}
		if (destinations > 0) {
			this.$monkSystems.push(systems[i]);
			this.$monkSystemIDs.push(systems[i].systemID);
		}
	}
}

this.playerWillSaveGame = function() {
	if (this.$contract) {
		missionVariables.blackmonk_contract = JSON.stringify(this.$contract);
	}
}

this.startUpComplete = this.shipDockedWithStation = function() {
	if (player.ship.dockedStation.name === "Black Monk Monastery") {
		player.ship.dockedStation.setInterface("blackmonks",{ 
			title: expandMissionText("monk_interface_title"),
			category: "Contracts",
			summary: expandMissionText("monk_interface_summary"),
			callback: this._bankingInterface.bind(this)
		});
	}
}

this.shipWillDockWithStation = function(station) {
	//offer payback on docking
	this.$offerOnce = true;
}

//force payback the the player is late and the destination is correct
this.missionScreenOpportunity = function() {
	//one shot welcome screen
	if (this.$monkIntro && player.ship.dockedStation.name === "Black Monk Monastery") {
		mission.runScreen({
			titleKey: "monk_title",
			screenID: "blackmonks",
			messageKey: "monk_first_visit_one_off_intro", 
		});
		setScreenOverlay({ name: "monk.png", height: 480 });
		this.$monkIntro = false;
		missionVariables.blackmonk_intro = 1;
	}
	if (player.ship.dockedStation.name === "Black Monk Monastery" && this.$contract) {
		//correct destination
		if ((this.$contract.galaxy === galaxyNumber && this.$contract.system === system.ID) || this.$contract.galaxy !== galaxyNumber) {
			missionVariables.monk_dest_name = System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name;
			//late, force payback
			if (this.$contract["dealine"] - clock.seconds < 0) {
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_late",
						choicesKey: "monk_payback_force"
					},
					function (choice) {
						this._payback();
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
			}
			//enough credits
			else if (this.$offerOnce && player.credits >= 30000) {screenID: "blackmonks",
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_early", 
						choicesKey: "monk_payback_choices"
					},
					function (choice) {
						if (choice === "1_YES") {
							this._payback();
						}
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
			}
			delete missionVariables.monk_dest_name;
		}
	}
	this.$offerOnce = false;
}

this._bankingInterface = function(page) {
	//contract running
	if (this.$contract) {
		//correct destination early with sufficient credits
		if (((this.$contract.galaxy === galaxyNumber && this.$contract.system === system.ID) || (this.$contract.galaxy !== galaxyNumber)) && player.credits >= 30000) {
			mission.runScreen({
					titleKey: "monk_title",
					screenID: "blackmonks",
					messageKey: "monk_payback_early", 
					choicesKey: "monk_payback_choices",
					exitScreen: "GUI_SCREEN_INTERFACES"
				},
				function (choice) {
					if (choice === "1_YES") {
						this._payback();
					}
				}
			);
		}
		//wrong destination or early without sufficient funds
		else {
			missionVariables.monk_dest_name = System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name;	//in time, godspeed to the player
			if (this.$contract["dealine"] - clock.seconds >= 0) {
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_wrong_destination", 
						exitScreen: "GUI_SCREEN_INTERFACES"
					}
				);
			}
			//too late, hurry the player up
			else {
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_wrong_destination_late", 
						exitScreen: "GUI_SCREEN_INTERFACES"
					}
				);			
			}
			delete missionVariables.monk_dest_name;
		}
		setScreenOverlay({ name: "monk.png", height: 480 });
	}
	//offer contract, if there isn't one running
	else {
		switch (page) {
			case "blackmonks": 
				//only offer for hyperspace capable ships
				if (player.ship.hasHyperspaceMotor) {
					mission.runScreen({
							titleKey: "monk_title",
							screenID: "blackmonks",
							messageKey: "monk_welcome", 
							choicesKey: "monk_welcome_choices",
							exitScreen: "GUI_SCREEN_INTERFACES"
						},
						function (choice) {
							if (choice === "1_YES") {
								this._bankingInterface("offer_list");
							}
						}
					);
				}
				else {
					mission.runScreen({
							titleKey: "monk_title",
							screenID: "blackmonks",
							messageKey: "monk_welcome_no_dice", 
							exitScreen: "GUI_SCREEN_INTERFACES"
						}
					);
				}
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
			case "offer_list":
				this.$destinations = new Array();
				for (var i = 0; i < this.$monkSystems.length; i++) {
					var routeInfo = system.info.routeToSystem(this.$monkSystems[i]);
					if (routeInfo && routeInfo.route.length > 9) {
						this.$destinations.push(this.$monkSystems[i]);
					}
				}

				//offer max five shortest routest
				this.$destinations.sort(function(a, b){return system.info.routeToSystem(a).route.length - system.info.routeToSystem(b).route.length});
				if (this.$destinations.length > 5) {
					this.$destinations = this.$destinations.slice(0, 5);
				}
				var options = {};
				for (var i = 0; i < this.$destinations.length; i++) {
					var info = system.info.routeToSystem(this.$destinations[i]);
					var origHours = info.time;
					var days = Math.ceil(origHours/24) + Math.ceil(info.route.length / 12); //extra 0.5 hours per system on route rounded up
					var distance = System.infoForSystem(galaxyNumber, system.ID).distanceToSystem(this.$destinations[i]).toFixed(1);
					options[i+"_DEST"] = this.$destinations[i].name + ", " + distance + " light years in " + days + " days";
				}
				options["99_EXIT"] = "Exit";
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_offer_list",
						choices: options,
						exitScreen: "GUI_SCREEN_INTERFACES"
					}, 
					function (choice) {
						if (choice !== "99_EXIT") {
							this.$offerPointer = choice.split('_')[0];
							this._setOffer("init");
							this.$mapMode = "LONG_RANGE_CHART_SHORTEST";
							this.$prevChoice = "3_NEXT";
							this.$restoreDestination = player.ship.targetSystem;
							this._bankingInterface("offer_map");
						}
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
			case "offer_map":
				player.ship.hudHidden = true;
				player.ship.targetSystem = this.$destinations[this.$offerPointer].systemID;
				
				var options = new Object;
				options["2_PREV"] = expandMissionText("monk_map_prev");
				options["3_NEXT"] = expandMissionText("monk_map_next");
				options["4_BACK"] = expandMissionText("monk_map_back");
				options["5_SIGN"] = expandMissionText("monk_map_sign");
				options["6_EXIT"] = expandMissionText("monk_map_exit");
				if (player.ship.equipmentStatus("EQ_ADVANCED_NAVIGATIONAL_ARRAY") === "EQUIPMENT_OK") {
					if (this.$mapMode === "LONG_RANGE_CHART_SHORTEST") {
						options["1_MODE"] = expandMissionText("monk_map_mode1");
					}
					else {
						options["1_MODE"] = expandMissionText("monk_map_mode2");
					}
				}

				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks-map",
						backgroundSpecial: this.$mapMode,
						messageKey: "monk_offer_details",
						choices: options,
						exitScreen: "GUI_SCREEN_INTERFACES",
						initialChoicesKey: this.$prevChoice
					},
					function (choice) {
						this.$prevChoice = choice;
						if (choice === "1_MODE") {
							if (this.$mapMode === "LONG_RANGE_CHART_SHORTEST") {
								this.$mapMode = "LONG_RANGE_CHART_QUICKEST";
							}
							else {
								this.$mapMode = "LONG_RANGE_CHART_SHORTEST";
							}
							this._bankingInterface("offer_map");
						}
						else if (choice === "3_NEXT") {
							this._setOffer("next");
							this._bankingInterface("offer_map");
						}
						else if (choice === "2_PREV") {
							this._setOffer("prev");
							this._bankingInterface("offer_map");
						}
						else if (choice === "4_BACK") {
							this._cleanUp();
							this._bankingInterface("offer_list");
						}
						else if (choice === "5_SIGN") {
							player.ship.hudHidden = false;
							this._bankingInterface("offer_sign");
						}
						else this._cleanUp();
					}
				);
				break;
			case "offer_sign":
				mission.runScreen({
						titleKey: "monk_title",
						messageKey: "monk_offer_sign",
						screenID: "blackmonks",
						exitScreen: "GUI_SCREEN_INTERFACES"
					}
				);
				//tip the player about the ANA
				if (player.ship.equipmentStatus("EQ_ADVANCED_NAVIGATIONAL_ARRAY") !== "EQUIPMENT_OK") {				
					mission.addMessageTextKey("monk_offer_sign_tip");
				}
				this._cleanUp();
				this.$contract = new Object;
				this.$contract["galaxy"] = galaxyNumber;
				this.$contract["system"] = this.$destinations[this.$offerPointer].systemID;
				this.$contract["dealine"] = clock.seconds + this.$days * 86400;
				player.credits += 20000;
				mission.markSystem({system: this.$contract["system"], name: "blackmonks"});
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
		}
	}
}

this._payback = function() {
	//clear the marker
	mission.unmarkSystem({system: this.$contract["system"], name: "blackmonks"});
	//enough credits
	if (player.credits >= 30000) {
		player.credits -= 30000;
		delete this.$contract;
		mission.runScreen({
				titleKey: "monk_title",
				messageKey: "monk_payback_enough",
				screenID: "blackmonks"
			}
		);
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
	}
	//not enough credits, but enough equipment
	else if (this._evaluateEquipment() + player.credits >= 30000) {
		var sellOutcome = this._sellEquipment();
		missionVariables.monk_equipment_total = formatCredits(sellOutcome[1], true, true);
		missionVariables.monk_equipment_list = sellOutcome[0].join(", ");
		player.credits -= 30000;
		delete this.$contract;
		mission.runScreen({
				titleKey: "monk_title",
				messageKey: "monk_payback_not_enough",
				screenID: "blackmonks"
			}
		);
		mission.addMessageTextKey("monk_payback_equipment");
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
		delete missionVariables.monk_equipment_total;
		delete missionVariables.monk_equipment_list;
	}
	//not enough credits, not enough equipment, have to sell the ship
	else {
		var sellOutcome = this._sellEquipment();
		missionVariables.monk_equipment_total = formatCredits(sellOutcome[1], true, true);
		missionVariables.monk_equipment_list = sellOutcome[0].join(", ");
		missionVariables.monk_old_ship = formatCredits(0.5 * player.ship.price, true, true);
		this._sellShip();
		missionVariables.monk_new_ship = formatCredits(player.ship.price, true, true);
		player.credits -= 30000;
		player.credits -= player.ship.price;
		delete this.$contract;
		player.ship.hudHidden = true;
		mission.runScreen({
				titleKey: "monk_title",
				messageKey: "monk_payback_not_nearly_enough",
				screenID: "blackmonks"
			}
		);
		missionVariables.monk_balance = formatCredits(player.credits, true, true);	
		mission.addMessageTextKey("monk_payback_equipment");
		mission.addMessageTextKey("monk_payback_ship");
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
		
		delete missionVariables.monk_equipment_total;
		delete missionVariables.monk_equipment_list;
		delete missionVariables.monk_old_ship;
		delete missionVariables.monk_new_ship;
		delete missionVariables.monk_balance;
	}
}

//calculate the value of weapons, missiles and the installed equipment
this._evaluateEquipment = function() {
	var value = 0;
	var equipments = player.ship.equipment;
	for (var i = 0; i < equipments.length; i++) {
		if (equipments[i].price > 0 && player.ship.equipmentStatus(equipments[i]) === "EQUIPMENT_OK" && equipments[i].equipmentKey !== "EQ_CARGO_BAY" && equipments[i].equipmentKey !== "EQ_PASSENGER_BERTH") {
			value += equipments[i].price;
		}
	}
	var missiles = player.ship.missiles;
	for (var i = 0; i < missiles.length; i++) {
		if (missiles[i].price > 0) {
			value += missiles[i].price;
		}
	}
	if (player.ship.portWeapon && player.ship.portWeapon.price > 0) {
		value += player.ship.portWeapon.price;
	}
	if (player.ship.aftWeapon && player.ship.aftWeapon.price > 0) {
		value += player.ship.aftWeapon.price;
	}
	if (player.ship.starboardWeapon && player.ship.starboardWeapon.price > 0) {
		value += player.ship.starboardWeapon.price;
	}
	if (player.ship.forwardWeapon && player.ship.forwardWeapon.price > 0) {
		value += player.ship.forwardWeapon.price;
	}
	return value / 10;
}

//pay with equipment
this._sellEquipment = function() {
	
	var stripped = new Array();
	var oldBalance = player.credits;
	
	//strip the missiles
	var missiles = player.ship.missiles;
	for (var i = 0; i < missiles.length; i++) {
		if (player.credits < 30000) {
			if (missiles[i].price > 0) {
				player.credits += missiles[i].price / 10;
				stripped.push(missiles[i].name);
				player.ship.removeEquipment(missiles[i]);
			}
		}
	}
	//strip equipment except for LCB and berths. EQ_CARGO_BAY,EQ_PASSENGER_BERTH
	var equipments = player.ship.equipment;
	for (var i = 0; i < equipments.length; i++) {
		if (player.credits < 30000) {
			if (equipments[i].price > 0 && player.ship.equipmentStatus(equipments[i]) === "EQUIPMENT_OK" && equipments[i].equipmentKey !== "EQ_CARGO_BAY" && equipments[i].equipmentKey !== "EQ_PASSENGER_BERTH") {
				player.credits += equipments[i].price / 10;
				stripped.push(equipments[i].name);
				player.ship.removeEquipment(equipments[i]);
			}
		}
	}
	//strip lasers
	if (player.credits < 30000) {
		if (player.ship.portWeapon && player.ship.portWeapon.price > 0) {
			player.credits += player.ship.portWeapon.price / 10;
			stripped.push([player.ship.portWeapon.name, player.ship.portWeapon.price / 10]);
			player.ship.boardWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.starboardWeapon && player.ship.starboardWeapon.price > 0) {
			player.credits += player.ship.starboardWeapon.price / 10;
			stripped.push(player.ship.starboardWeapon.name);
			player.ship.starboardWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.aftWeapon && player.ship.aftWeapon.price > 0) {
			player.credits += player.ship.aftWeapon.price / 10;
			stripped.push(player.ship.aftWeapon.name);
			player.ship.aftWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.forwardWeapon && player.ship.forwardWeapon.price > 0) {
			player.credits += player.ship.forwardWeapon.price / 10;
			stripped.push(player.ship.forwardWeapon.name);
			player.ship.forwardWeapon = null;
		}
	}
	
	
	return([stripped, player.credits - oldBalance]);
}

this._sellShip = function() {
	//no matter in what condition the player ship is, always sell for 50% of mint price
	var refundFactor = 0.5;
	player.credits += player.ship.price * refundFactor;
	player.replaceShip("adder-player");
	player.ship.removeEquipment("EQ_HEAT_SHIELD");
	player.ship.removeEquipment("EQ_MISSILE");
	player.ship.serviceLevel = 75;
}


//clean up mission variables and restore target system
this._cleanUp = function() {
	if (missionVariables.monk_dest_name) {
		player.ship.hudHidden = false;
		delete missionVariables.monk_dest_name;
		delete missionVariables.monk_time;
		delete missionVariables.monk_deadline;
		player.ship.targetSystem = this.$restoreDestination;
	}
}

this.guiScreenWillChange = function(to, from) {
	if (this.$contract && to === "GUI_SCREEN_MANIFEST") {
		var secsLeft = this.$contract["dealine"] - clock.seconds;
		var hoursLeft = Math.floor((secsLeft) / 3600);
		if (hoursLeft > 0) {
			var daysText = " in " + hoursLeft + " hours.";
		}
		else if (hoursLeft === 0) {
			var daysText = " in less than an hour!";
		}
		else var daysText = ". Deadline has passed!";
		mission.setInstructions("Pay 30 000 credits to the Black Monk Monastery at " + System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name + daysText);
	}
	else if (!this.$contract) {
		player.ship.hudHidden = false;
		mission.setInstructions(null);
	}
}

this._setOffer = function(action) {
	if (action === "next") {
		this.$offerPointer++;
		if (this.$offerPointer >= this.$destinations.length) {
			this.$offerPointer = 0;
		}
	}
	else if (action === "prev") {
		this.$offerPointer--;
		if (this.$offerPointer <= 0) {
			this.$offerPointer = this.$destinations.length - 1;
		}
	}
	var info = system.info.routeToSystem(this.$destinations[this.$offerPointer]);
	var origHours = info.time;
	this.$days = Math.ceil(origHours/24) + Math.ceil(info.route.length / 12);//0.5 hours per system on route rounded up to full days
	missionVariables.monk_dest_name = this.$destinations[this.$offerPointer].name;
	missionVariables.monk_time = this.$days + " days (" + this.$days * 24 + " hours)";
	missionVariables.monk_deadline = clock.days + this.$days;
}

this.systemWillPopulate = function() {

	if (this.$monkSystemIDs.indexOf(system.ID) !== -1) {
		system.setPopulator("blackmonk_station", {
			
			callback: function(pos) {
				var monastery = system.addShips("blackmonk_monastery", 1, pos, 0)[0];
				monastery.orientation = [1, 0, 1, 0];
				var minesweepers = system.addShips("blackmonk_minesweeper", 10, pos, 15E3);
				for (var i = 0; i < minesweepers.length; i++) {
					//init the alert mechanism of minesweepers.
					minesweepers[i].script.$mother = monastery;
				}
			}.bind(this),
			location: "LANE_WP",
			locationSeed: 937,
			deterministic: true
		});
	}
	
	//retribution time
	
	//now the player is in trouble. increasing number of gunships are being spawned close to the witchpoint every time the player enters a system.
	if (this.$contract && this.$contract["dealine"] - clock.seconds < 0) {
		var count = Math.ceil((clock.seconds -this.$contract["dealine"]) / 86400);
		if (count > 5) count = 5;
		system.setPopulator("blackmonk_punishers", {
			callback: function(pos) {
				system.addGroup("blackmonk_gunship", count, pos);
			}.bind(this),
			location: "WITCHPOINT"
		});
	}
	
	//ambiance
	
	//gunships are ridiculously powerful, but very rare. roughly every tenth system has one cruising. running contract doubles the odds to start with and ramps them up close to the deadline.
	if (this.$contract) {
		var div = (Math.ceil(this.$contract["dealine"] - clock.seconds) / 86400);
		if (div >= 2) {
			var prob = 2 / (Math.ceil(this.$contract["dealine"] - clock.seconds) / 86400);
			if (prob < 0.2) prob = 0.2;
		}
		else var prob = 1;
	}
	else var prob = 0.1;
	
	if (Math.random() < prob) {
		system.setPopulator("blackmonk_ambiance_gunship", {
			callback: function(pos) {
				//half the time, spawn ambiance ships close to the witchpoint and move them a bit closer to the planet. a bit is a 0.75 * scanner range. it's a bit boring to all the time have them sitting next to the witchpoint. a bit too staged to my liking.
				if (Math.random() < 0.5) {
					var gunship = system.addShips("blackmonk_gunship", 1)[0];
					gunship.position = gunship.position.add([0, 0, 19200]);
					var debtor = system.addShips("trader", 1, gunship.position)[0];
				}
				else {
					var gunship = system.addShips("blackmonk_gunship", 1, pos)[0];
					var debtor = system.addShips("trader", 1, gunship.position)[0];
				}
				debtor.$monkDebtor = true;
				debtor.fuel = 0;//no escape
			}.bind(this),
			location: "LANE_WP"
		});
		//this is a long shot, a lonely debtor leisurely cruising the lane. with some seriusly bad load of luck it just might meet a blackmonk gunship.
		system.setPopulator("blackmonk_ambiance_wandering_debtor", {
			callback: function(pos) {
				var debtor = system.addShips("trader", 1, pos)[0];
				debtor.$monkDebtor = true;
				debtor.fuel = 0;//no escape
			}.bind(this),
			location: "LANE_WP"
		});
	}
}
Scripts/blackmonk_minesweeper.js
"use strict";

this.name           = "blackmonk_minesweeper";
this.description    = "Minesweeper ship script.";

//this.$mother is set from the populator

this.shipBeingAttacked = function(whom){
	//relay attack to the possible mother
	if (this.$mother) {
		this.$mother.script.shipBeingAttacked(whom);
		this.$mother.AIScript.shipBeingAttacked(whom);
	}
}
Scripts/blackmonk_station.js
"use strict";

this.name           = "blackmonk_station";
this.description    = "Monastery ship script.";

//give a hostile player a warning when fired upon.
this.shipBeingAttacked = function(whom){
	var aiScript = ship.AIScript;
	if (whom.isPlayer && aiScript.$warn) {
		aiScript.$warn = false;
		ship.commsMessage("[monk-warning]");
		if (aiScript.$adTimer) {
			aiScript.$adTimer.stop();
			delete aiScript.$adTimer;
		}
	}
}
Scripts/copy of blackmonk_main.js
"use strict";

this.name               = "blackmonks";
this.author				= "spara";
this.description		= "Main script for Black Monks";

this.startUp = function() {
	if (missionVariables.blackmonk_contract) {
		this.$contract = JSON.parse(missionVariables.blackmonk_contract);
		delete missionVariables.blackmonk_contract;
	}
	this._setMonkSystems();
	//control payback on docking
	this.$offerOnce = false;
}

this.playerEnteredNewGalaxy = function() {
	this._setMonkSystems();
}

//make a list of suitable monk systems
this._setMonkSystems = function() {
	this.$monkSystems = new Array();
	this.$monkSystemIDs = new Array();
	
	//first we'll utilize the basic rules
	var systems = SystemInfo.filteredSystems(this, function(other) {
		if (other.government >= 6 && other.techlevel >= 11 && !other.sun_gone_nova) {
			return (other);
		}
	});
	
	//only systems that are connected to others so that missions work are accepted
	for (var i = 0; i < systems.length; i++) {
		var destinations = 0;
		for (var j = 0; j < systems.length; j++) {
			var routeInfo = System.infoForSystem(galaxyNumber, systems[i].systemID).routeToSystem(systems[j]);
			if (routeInfo && routeInfo.route.length > 9) destinations++;
		}
		if (destinations > 0) {
			this.$monkSystems.push(systems[i]);
			this.$monkSystemIDs.push(systems[i].systemID);
		}
	}
}

this.playerWillSaveGame = function() {
	if (this.$contract) {
		missionVariables.blackmonk_contract = JSON.stringify(this.$contract);
	}
}

this.startUpComplete = this.shipDockedWithStation = function() {
	if (player.ship.dockedStation.name === "Black Monk Monastery") {
		player.ship.dockedStation.setInterface("blackmonks",{ 
			title: expandMissionText("monk_interface_title"),
			category: "Contracts",
			summary: expandMissionText("monk_interface_summary"),
			callback: this._bankingInterface.bind(this)
		});
	}
}

this.shipWillDockWithStation = function(station) {
	//offer payback on docking
	this.$offerOnce = true;
}

//force payback the the player is late and the destination is correct
this.missionScreenOpportunity = function() {
	if (player.ship.dockedStation.name === "Black Monk Monastery" && this.$contract) {
		//correct destination
		if ((this.$contract.galaxy === galaxyNumber && this.$contract.system === system.ID) || this.$contract.galaxy !== galaxyNumber) {
			missionVariables.monk_dest_name = System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name;
			//late, force payback
			if (this.$contract["dealine"] - clock.seconds < 0) {
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_late",
						choicesKey: "monk_payback_force"
					},
					function (choice) {
						this._payback();
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
			}
			//enough credits
			else if (this.$offerOnce && player.credits >= 30000) {screenID: "blackmonks",
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_early", 
						choicesKey: "monk_payback_choices"
					},
					function (choice) {
						if (choice === "1_YES") {
							this._payback();
						}
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
			}
			delete missionVariables.monk_dest_name;
		}
	}
	this.$offerOnce = false;
}

this._bankingInterface = function(page) {
	//contract running
	if (this.$contract) {
		//correct destination early with sufficient credits
		if (((this.$contract.galaxy === galaxyNumber && this.$contract.system === system.ID) || (this.$contract.galaxy !== galaxyNumber)) && player.credits >= 30000) {
			mission.runScreen({
					titleKey: "monk_title",
					screenID: "blackmonks",
					messageKey: "monk_payback_early", 
					choicesKey: "monk_payback_choices",
					exitScreen: "GUI_SCREEN_INTERFACES"
				},
				function (choice) {
					if (choice === "1_YES") {
						this._payback();
					}
				}
			);
		}
		//wrong destination or early without sufficient funds
		else {
			missionVariables.monk_dest_name = System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name;	//in time, godspeed to the player
			if (this.$contract["dealine"] - clock.seconds >= 0) {
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_wrong_destination", 
						exitScreen: "GUI_SCREEN_INTERFACES"
					}
				);
			}
			//too late, hurry the player up
			else {
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_payback_wrong_destination_late", 
						exitScreen: "GUI_SCREEN_INTERFACES"
					}
				);			
			}
			delete missionVariables.monk_dest_name;
		}
		setScreenOverlay({ name: "monk.png", height: 480 });
	}
	//offer contract, if there isn't one running
	else {
		switch (page) {
			case "blackmonks": 
				//only offer for hyperspace capable ships
				if (player.ship.hasHyperspaceMotor) {
					mission.runScreen({
							titleKey: "monk_title",
							screenID: "blackmonks",
							messageKey: "monk_welcome", 
							choicesKey: "monk_welcome_choices",
							exitScreen: "GUI_SCREEN_INTERFACES"
						},
						function (choice) {
							if (choice === "1_YES") {
								this._bankingInterface("offer_list");
							}
						}
					);
				}
				else {
					mission.runScreen({
							titleKey: "monk_title",
							screenID: "blackmonks",
							messageKey: "monk_welcome_no_dice", 
							exitScreen: "GUI_SCREEN_INTERFACES"
						}
					);
				}
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
			case "offer_list":
				this.$destinations = new Array();
				for (var i = 0; i < this.$monkSystems.length; i++) {
					var routeInfo = system.info.routeToSystem(this.$monkSystems[i]);
					if (routeInfo && routeInfo.route.length > 9) {
						this.$destinations.push(this.$monkSystems[i]);
					}
				}

				//offer max five shortest routest
				this.$destinations.sort(function(a, b){return system.info.routeToSystem(a).route.length - system.info.routeToSystem(b).route.length});
				if (this.$destinations.length > 5) {
					this.$destinations = this.$destinations.slice(0, 5);
				}
				var options = {};
				for (var i = 0; i < this.$destinations.length; i++) {
					var info = system.info.routeToSystem(this.$destinations[i]);
					var origHours = info.time;
					var days = Math.ceil(origHours/24) + Math.ceil(info.route.length / 12); //extra 0.5 hours per system on route rounded up
					var distance = System.infoForSystem(galaxyNumber, system.ID).distanceToSystem(this.$destinations[i]).toFixed(1);
					options[i+"_DEST"] = this.$destinations[i].name + ", " + distance + " light years in " + days + " days";
				}
				options["99_EXIT"] = "Exit";
				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks",
						messageKey: "monk_offer_list",
						choices: options,
						exitScreen: "GUI_SCREEN_INTERFACES"
					}, 
					function (choice) {
						if (choice !== "99_EXIT") {
							this.$offerPointer = choice.split('_')[0];
							this._setOffer("init");
							this.$mapMode = "LONG_RANGE_CHART_SHORTEST";
							this.$prevChoice = "3_NEXT";
							this.$restoreDestination = player.ship.targetSystem;
							this._bankingInterface("offer_map");
						}
					}
				);
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
			case "offer_map":
				player.ship.hudHidden = true;
				player.ship.targetSystem = this.$destinations[this.$offerPointer].systemID;
				
				var options = new Object;
				options["2_PREV"] = expandMissionText("monk_map_prev");
				options["3_NEXT"] = expandMissionText("monk_map_next");
				options["4_BACK"] = expandMissionText("monk_map_back");
				options["5_SIGN"] = expandMissionText("monk_map_sign");
				options["6_EXIT"] = expandMissionText("monk_map_exit");
				if (player.ship.equipmentStatus("EQ_ADVANCED_NAVIGATIONAL_ARRAY") === "EQUIPMENT_OK") {
					if (this.$mapMode === "LONG_RANGE_CHART_SHORTEST") {
						options["1_MODE"] = expandMissionText("monk_map_mode1");
					}
					else {
						options["1_MODE"] = expandMissionText("monk_map_mode2");
					}
				}

				mission.runScreen({
						titleKey: "monk_title",
						screenID: "blackmonks-map",
						backgroundSpecial: this.$mapMode,
						messageKey: "monk_offer_details",
						choices: options,
						exitScreen: "GUI_SCREEN_INTERFACES",
						initialChoicesKey: this.$prevChoice
					},
					function (choice) {
						this.$prevChoice = choice;
						if (choice === "1_MODE") {
							if (this.$mapMode === "LONG_RANGE_CHART_SHORTEST") {
								this.$mapMode = "LONG_RANGE_CHART_QUICKEST";
							}
							else {
								this.$mapMode = "LONG_RANGE_CHART_SHORTEST";
							}
							this._bankingInterface("offer_map");
						}
						else if (choice === "3_NEXT") {
							this._setOffer("next");
							this._bankingInterface("offer_map");
						}
						else if (choice === "2_PREV") {
							this._setOffer("prev");
							this._bankingInterface("offer_map");
						}
						else if (choice === "4_BACK") {
							this._cleanUp();
							this._bankingInterface("offer_list");
						}
						else if (choice === "5_SIGN") {
							player.ship.hudHidden = false;
							this._bankingInterface("offer_sign");
						}
						else this._cleanUp();
					}
				);
				break;
			case "offer_sign":
				mission.runScreen({
						titleKey: "monk_title",
						messageKey: "monk_offer_sign",
						screenID: "blackmonks",
						exitScreen: "GUI_SCREEN_INTERFACES"
					}
				);
				//tip the player about the ANA
				if (player.ship.equipmentStatus("EQ_ADVANCED_NAVIGATIONAL_ARRAY") !== "EQUIPMENT_OK") {				
					mission.addMessageTextKey("monk_offer_sign_tip");
				}
				this._cleanUp();
				this.$contract = new Object;
				this.$contract["galaxy"] = galaxyNumber;
				this.$contract["system"] = this.$destinations[this.$offerPointer].systemID;
				this.$contract["dealine"] = clock.seconds + this.$days * 86400;
				player.credits += 20000;
				mission.markSystem({system: this.$contract["system"], name: "blackmonks"});
				setScreenOverlay({ name: "monk.png", height: 480 });
				break;
		}
	}
}

this._payback = function() {
	//clear the marker
	mission.unmarkSystem({system: this.$contract["system"], name: "blackmonks"});
	//enough credits
	if (player.credits >= 30000) {
		player.credits -= 30000;
		delete this.$contract;
		mission.runScreen({
				titleKey: "monk_title",
				messageKey: "monk_payback_enough",
				screenID: "blackmonks"
			}
		);
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
	}
	//not enough credits, but enough equipment
	else if (this._evaluateEquipment() + player.credits >= 30000) {
		var sellOutcome = this._sellEquipment();
		missionVariables.monk_equipment_total = formatCredits(sellOutcome[1], true, true);
		missionVariables.monk_equipment_list = sellOutcome[0].join(", ");
		player.credits -= 30000;
		delete this.$contract;
		mission.runScreen({
				titleKey: "monk_title",
				messageKey: "monk_payback_not_enough",
				screenID: "blackmonks"
			}
		);
		mission.addMessageTextKey("monk_payback_equipment");
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
		delete missionVariables.monk_equipment_total;
		delete missionVariables.monk_equipment_list;
	}
	//not enough credits, not enough equipment, have to sell the ship
	else {
		var sellOutcome = this._sellEquipment();
		missionVariables.monk_equipment_total = formatCredits(sellOutcome[1], true, true);
		missionVariables.monk_equipment_list = sellOutcome[0].join(", ");
		missionVariables.monk_old_ship = formatCredits(0.5 * player.ship.price, true, true);
		this._sellShip();
		missionVariables.monk_new_ship = formatCredits(player.ship.price, true, true);
		player.credits -= 30000;
		player.credits -= player.ship.price;
		delete this.$contract;
		player.ship.hudHidden = true;
		mission.runScreen({
				titleKey: "monk_title",
				messageKey: "monk_payback_not_nearly_enough",
				screenID: "blackmonks"
			}
		);
		missionVariables.monk_balance = formatCredits(player.credits, true, true);	
		mission.addMessageTextKey("monk_payback_equipment");
		mission.addMessageTextKey("monk_payback_ship");
		mission.addMessageTextKey("monk_payback_welcome_back");
		setScreenOverlay({ name: "monk.png", height: 480 });
		
		delete missionVariables.monk_equipment_total;
		delete missionVariables.monk_equipment_list;
		delete missionVariables.monk_old_ship;
		delete missionVariables.monk_new_ship;
		delete missionVariables.monk_balance;
	}
}

//calculate the value of weapons, missiles and the installed equipment
this._evaluateEquipment = function() {
	var value = 0;
	var equipments = player.ship.equipment;
	for (var i = 0; i < equipments.length; i++) {
		if (equipments[i].price > 0 && player.ship.equipmentStatus(equipments[i]) === "EQUIPMENT_OK" && equipments[i].equipmentKey !== "EQ_CARGO_BAY" && equipments[i].equipmentKey !== "EQ_PASSENGER_BERTH") {
			value += equipments[i].price;
		}
	}
	var missiles = player.ship.missiles;
	for (var i = 0; i < missiles.length; i++) {
		if (missiles[i].price > 0) {
			value += missiles[i].price;
		}
	}
	if (player.ship.portWeapon && player.ship.portWeapon.price > 0) {
		value += player.ship.portWeapon.price;
	}
	if (player.ship.aftWeapon && player.ship.aftWeapon.price > 0) {
		value += player.ship.aftWeapon.price;
	}
	if (player.ship.starboardWeapon && player.ship.starboardWeapon.price > 0) {
		value += player.ship.starboardWeapon.price;
	}
	if (player.ship.forwardWeapon && player.ship.forwardWeapon.price > 0) {
		value += player.ship.forwardWeapon.price;
	}
	return value / 10;
}

//pay with equipment
this._sellEquipment = function() {
	
	var stripped = new Array();
	var oldBalance = player.credits;
	
	//strip the missiles
	var missiles = player.ship.missiles;
	for (var i = 0; i < missiles.length; i++) {
		if (player.credits < 30000) {
			if (missiles[i].price > 0) {
				player.credits += missiles[i].price / 10;
				stripped.push(missiles[i].name);
				player.ship.removeEquipment(missiles[i]);
			}
		}
	}
	//strip equipment except for LCB and berths. EQ_CARGO_BAY,EQ_PASSENGER_BERTH
	var equipments = player.ship.equipment;
	for (var i = 0; i < equipments.length; i++) {
		if (player.credits < 30000) {
			if (equipments[i].price > 0 && player.ship.equipmentStatus(equipments[i]) === "EQUIPMENT_OK" && equipments[i].equipmentKey !== "EQ_CARGO_BAY" && equipments[i].equipmentKey !== "EQ_PASSENGER_BERTH") {
				player.credits += equipments[i].price / 10;
				stripped.push(equipments[i].name);
				player.ship.removeEquipment(equipments[i]);
			}
		}
	}
	//strip lasers
	if (player.credits < 30000) {
		if (player.ship.portWeapon && player.ship.portWeapon.price > 0) {
			player.credits += player.ship.portWeapon.price / 10;
			stripped.push([player.ship.portWeapon.name, player.ship.portWeapon.price / 10]);
			player.ship.boardWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.starboardWeapon && player.ship.starboardWeapon.price > 0) {
			player.credits += player.ship.starboardWeapon.price / 10;
			stripped.push(player.ship.starboardWeapon.name);
			player.ship.starboardWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.aftWeapon && player.ship.aftWeapon.price > 0) {
			player.credits += player.ship.aftWeapon.price / 10;
			stripped.push(player.ship.aftWeapon.name);
			player.ship.aftWeapon = null;
		}
	}
	if (player.credits < 30000) {
		if (player.ship.forwardWeapon && player.ship.forwardWeapon.price > 0) {
			player.credits += player.ship.forwardWeapon.price / 10;
			stripped.push(player.ship.forwardWeapon.name);
			player.ship.forwardWeapon = null;
		}
	}
	
	
	return([stripped, player.credits - oldBalance]);
}

this._sellShip = function() {
	//no matter in what condition the player ship is, always sell for 50% of mint price
	var refundFactor = 0.5;
	player.credits += player.ship.price * refundFactor;
	player.replaceShip("adder-player");
	player.ship.removeEquipment("EQ_HEAT_SHIELD");
	player.ship.removeEquipment("EQ_MISSILE");
	player.ship.serviceLevel = 75;
}


//clean up mission variables and restore target system
this._cleanUp = function() {
	if (missionVariables.monk_dest_name) {
		player.ship.hudHidden = false;
		delete missionVariables.monk_dest_name;
		delete missionVariables.monk_time;
		delete missionVariables.monk_deadline;
		player.ship.targetSystem = this.$restoreDestination;
	}
}

this.guiScreenWillChange = function(to, from) {
	if (this.$contract && to === "GUI_SCREEN_MANIFEST") {
		var secsLeft = this.$contract["dealine"] - clock.seconds;
		var hoursLeft = Math.floor((secsLeft) / 3600);
		if (hoursLeft > 0) {
			var daysText = " in " + hoursLeft + " hours.";
		}
		else if (hoursLeft === 0) {
			var daysText = " in less than an hour!";
		}
		else var daysText = ". Deadline has passed!";
		mission.setInstructions("Pay 30 000 credits to the Black Monk Monastery at " + System.infoForSystem(this.$contract["galaxy"], this.$contract["system"]).name + daysText);
	}
	else if (!this.$contract) {
		player.ship.hudHidden = false;
		mission.setInstructions(null);
	}
}

this._setOffer = function(action) {
	if (action === "next") {
		this.$offerPointer++;
		if (this.$offerPointer >= this.$destinations.length) {
			this.$offerPointer = 0;
		}
	}
	else if (action === "prev") {
		this.$offerPointer--;
		if (this.$offerPointer <= 0) {
			this.$offerPointer = this.$destinations.length - 1;
		}
	}
	var info = system.info.routeToSystem(this.$destinations[this.$offerPointer]);
	var origHours = info.time;
	this.$days = Math.ceil(origHours/24) + Math.ceil(info.route.length / 12);//0.5 hours per system on route rounded up to full days
	missionVariables.monk_dest_name = this.$destinations[this.$offerPointer].name;
	missionVariables.monk_time = this.$days + " days (" + this.$days * 24 + " hours)";
	missionVariables.monk_deadline = clock.days + this.$days;
}

this.systemWillPopulate = function() {

	if (this.$monkSystemIDs.indexOf(system.ID) !== -1) {
		system.setPopulator("blackmonk_station", {
			
			callback: function(pos) {
				var monastery = system.addShips("blackmonk_monastery", 1, pos, 0)[0];
				monastery.orientation = [1, 0, 1, 0];
				var minesweepers = system.addShips("blackmonk_minesweeper", 10, pos, 15E3);
				for (var i = 0; i < minesweepers.length; i++) {
					//init the alert mechanism of minesweepers.
					minesweepers[i].script.$mother = monastery;
				}
			}.bind(this),
			location: "LANE_WP",
			locationSeed: 937,
			deterministic: true
		});
	}
	
	//retribution time
	
	//now the player is in trouble. increasing number of gunships are being spawned close to the witchpoint every time the player enters a system.
	if (this.$contract && this.$contract["dealine"] - clock.seconds < 0) {
		var count = Math.ceil((clock.seconds -this.$contract["dealine"]) / 86400);
		if (count > 5) count = 5;
		system.setPopulator("blackmonk_punishers", {
			callback: function(pos) {
				system.addGroup("blackmonk_gunship", count, pos);
			}.bind(this),
			location: "WITCHPOINT"
		});
	}
	
	//ambiance
	
	//gunships are ridiculously powerful, but very rare. roughly every tenth system has one cruising. running contract doubles the odds to start with and ramps them up close to the deadline.
	if (this.$contract) {
		var div = (Math.ceil(this.$contract["dealine"] - clock.seconds) / 86400);
		if (div >= 2) {
			var prob = 2 / (Math.ceil(this.$contract["dealine"] - clock.seconds) / 86400);
			if (prob < 0.2) prob = 0.2;
		}
		else var prob = 1;
	}
	else var prob = 0.1;
	
	if (Math.random() < prob) {
		system.setPopulator("blackmonk_ambiance_gunship", {
			callback: function(pos) {
				//half the time, spawn ambiance ships close to the witchpoint and move them a bit closer to the planet. a bit is a 0.75 * scanner range. it's a bit boring to all the time have them sitting next to the witchpoint. a bit too staged to my liking.
				if (Math.random() < 0.5) {
					var gunship = system.addShips("blackmonk_gunship", 1)[0];
					gunship.position = gunship.position.add([0, 0, 19200]);
					var debtor = system.addShips("trader", 1, gunship.position)[0];
				}
				else {
					var gunship = system.addShips("blackmonk_gunship", 1, pos)[0];
					var debtor = system.addShips("trader", 1, gunship.position)[0];
				}
				debtor.$monkDebtor = true;
				debtor.fuel = 0;//no escape
			}.bind(this),
			location: "LANE_WP"
		});
		//this is a long shot, a lonely debtor leisurely cruising the lane. with some seriusly bad load of luck it just might meet a blackmonk gunship.
		system.setPopulator("blackmonk_ambiance_wandering_debtor", {
			callback: function(pos) {
				var debtor = system.addShips("trader", 1, pos)[0];
				debtor.$monkDebtor = true;
				debtor.fuel = 0;//no escape
			}.bind(this),
			location: "LANE_WP"
		});
	}
}