| Scripts/nuit_space_station_populator.js | "use strict";
this.name = "nuit_space_station_populator";
this.author = "Montana05";
this.description = "Populator for Nuit Space Stations";
this.version = "2.0";
this.copyright = "2022 Montana05";
this.license = "CC BY-NC-SA 4.0";
this._externalDockNotification = false;
this._portNotification = false;
this._timer = null;
this._setStation = null;
this._externalDockFee = 100; // amount to charge for use of external dock
this._noAegisSpawn = true;
//----------------------------------------------------------------------------------------
this.startUpComplete = function () {
	// add docking fees
	if (worldScripts["Docking Fees"]) {
		worldScripts["Docking Fees"].$addFee("nuit_space_station", { messageKey: "dockfee_short" });
	}
}
//----------------------------------------------------------------------------------------
this.systemWillPopulate = function () {
	var systemGov = system.government;
	if (!this._setStation || !this._setStation.isValid) {
		if (this._timer && this._timer.isRunning) this._timer.stop();
	}
	// advanced systems with a Dictatorship, Confederacy, Democracy or Corporate State government
	if (system.isInterstellarSpace || system.sun.isGoingNova || system.sun.hasGoneNova ||
		system.techLevel < 10 || systemGov < 3 || systemGov == 4 || systemGov == 5 ||
		system.countShipsWithRole("nuit_space_station") > 0) {
		return;
	} else {
		// in rich industrial systems the Nuit Space Station is located close to the main station
		if (system.economy == 0 && this._noAegisSpawn == false) {
			system.setPopulator("nuit",
				{
					callback: function (pos) {
						var key = "nuit_space_station";
						// check if liners is installed
						if (worldScripts["liners_populator_script.js"]) key = "nuit_space_station_liners";
						var nuit_station = system.addShips(key, 1, pos, 0)[0];
						nuit_station.orientation = [1, 0, 1, 0];
						// add a ve to mask the issue of the walls of the dock disappearing when you enter
						var ve = system.addVisualEffect("nuit_dock_ve", nuit_station.position.add(nuit_station.vectorRight.multiply(-11)).add(nuit_station.vectorUp.multiply(3004)).add(nuit_station.vectorForward.multiply(419)));
						ve.scale(1.01);
						ve.orientation = nuit_station.orientation;
						worldScripts["nuit_space_station_populator"].$populateExternalDocks(nuit_station);
						if (worldScripts.ExternalDockSystem) worldScripts["nuit_space_station_populator"].$registerExternalDocks(nuit_station);
					}.bind(this),
					location: "STATION_AEGIS",
					locationSeed: 112,
					deterministic: true
				});
		} else {
			// in all other systems it could be found on the other side of the planet
			system.setPopulator("nuit",
				{
					callback: function (pos) {
						var key = "nuit_space_station";
						// check if liners is installed
						if (worldScripts["liners_populator_script.js"]) key = "nuit_space_station_liners";
						var pos = Vector3D(0.0, 0.0, -0.2).fromCoordinateSystem("pwu");
						var nuit_station = system.addShips(key, 1, pos, 0)[0];
						nuit_station.orientation = [1, 0, 1, 0];
						// add a ve to mask the issue of the walls of the dock disappearing when you enter
						var ve = system.addVisualEffect("nuit_dock_ve", nuit_station.position.add(nuit_station.vectorRight.multiply(-11)).add(nuit_station.vectorUp.multiply(3004)).add(nuit_station.vectorForward.multiply(419)));
						ve.scale(1.01);
						ve.orientation = nuit_station.orientation;
						worldScripts["nuit_space_station_populator"].$populateExternalDocks(nuit_station);
						if (worldScripts.ExternalDockSystem) worldScripts["nuit_space_station_populator"].$registerExternalDocks(nuit_station);
					}.bind(this),
					location: "COORDINATES",
					locationSeed: 112,
					deterministic: true
				});
		};
	};
};
//----------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = this.shipDied = function() {
	if (this._timer && this._timer.isRunning) this._timer.stop();
}
//----------------------------------------------------------------------------------------
this.$externalDockNotification = function $externalDockNotification() {
	if (!this._setStation || !this._setStation.isValid) {
		this._timer.stop();
		return;
	}
	if (this._externalDockNotification == false) {
		if (this._setStation.position.distanceTo(player.ship) < player.ship.scannerRange * 0.85) {
			this._setStation.commsMessage(expandDescription("[nuit_external_docks]", { fee_amt: formatCredits(this._externalDockFee, true, true) }), player.ship);
			this._externalDockNotification = true;
		}
	} else if (this._externalDockNotification == true && this._portNotification == false) {
		var areis = "are";
		if (this._setStation._externalDocks.length == 1) areis = "is";
		this._setStation.commsMessage(expandDescription("[nuit_external_available]", { available_ports: this._setStation._externalDocksAvailable, are_is: areis }), player.ship);
		this._portNotification = true;
	} else {
		this._timer.stop();
	}
}
//----------------------------------------------------------------------------------------
this.guiScreenChanged_hold = function (to, from) {
	// after all docking processes have finished, do the post dock functions
	if ((to == "GUI_SCREEN_REPORT" && from == "GUI_SCREEN_STATUS") ||
		(to == "GUI_SCREEN_STATUS" && from == "GUI_SCREEN_MAIN") ||
		(to == "GUI_SCREEN_STATUS" && from == "GUI_SCREEN_REPORT")) {
		this.$postDockSetup(player.ship.dockedStation);
		delete this.guiScreenChanged;
	}
}
//----------------------------------------------------------------------------------------
// works out which docks will have ships docked in them
this.$populateExternalDocks = function (station) {
	// docked ship subents are from index 11
	var num = parseInt(system.scrambledPseudoRandomNumber(clock.days) * 3); // number of ships to have docked (between 0 and 2) 
	var check = 0;
	var last = station.subEntities.length - 1; // index of the last entry
	var variations = parseInt(((last - 11) + 1) / 4);
	station._externalDocks = [];
	for (var i = 0; i <= 3; i++) { // number of external docking positions
		if (system.scrambledPseudoRandomNumber(clock.days * 2 + i) > 0.5 && check < num) {
			// only keep one in each position
			var keep = parseInt(system.scrambledPseudoRandomNumber(clock.days * 3 + i) * variations);
			var counter = 0;
			for (var j = (last - (i * variations)); j >= (last - (i * variations) - variations) + 1; j--) {
				if (counter != keep) {
					station.subEntities[j].remove();
				}
				counter += 1;
			}
			check += 1;
		} else {
			// we're removing all in this position
			for (var j = (last - (i * variations)); j >= (last - (i * variations) - variations) + 1; j--) {
				station.subEntities[j].remove();
			}
			station._externalDocks.push(i);
		}
	}
	// build text for dock number notification
	if (station._externalDocks.length > 0) {
		var txt = "";
		var add = ", ";
		for (var i = 0; i < station._externalDocks.length; i++) {
			if (i == station._externalDocks.length - 1) add = " and ";
			txt += (txt == "" ? "" : add) + "0" + (station._externalDocks[i] + 1);
		}
		station._externalDocksAvailable = txt;
	}
	// remove the flashers if eds is not installed.
	var eds = worldScripts.ExternalDockSystem;
	if (!eds) {
		station.subEntities[10].remove();
		station.subEntities[9].remove();
		station.subEntities[8].remove();
		station.subEntities[7].remove();
	}
}
//----------------------------------------------------------------------------------------
// registers our external docks with the eds
this.$registerExternalDocks = function (station) {
	var eds = worldScripts.ExternalDockSystem;
	this._setStation = station;
	// set up the timer to let the player know about the docks
	if (station._externalDocks.length > 0) this._timer = new Timer(this, this.$externalDockNotification, 2, 2);
	var docks = station._externalDocks.length;
	var dockmax = 4;
	// dock 0 - index 10
	if (station._externalDocks.indexOf(0) >= 0) {
		eds.$addExternalDock({station:station, position:[2400, 40, -20], scale:1, dockRange:300, allowLaunch:true, launchSubEntityIndex:(10 - (dockmax - docks)), preDockCallback:this.$preDockSetup.bind(this)});
	} else station.subEntities[10].remove();
	// dock 1 - index 9
	if (station._externalDocks.indexOf(1) >= 0) {
		dockmax = 4;
		if (station._externalDocks.indexOf(0) == -1) dockmax -= 1;
		eds.$addExternalDock({station:station, position:[-2400, 40, -20], scale:1, dockRange:300, allowLaunch:true, launchSubEntityIndex:(9 - (dockmax - docks)), preDockCallback:this.$preDockSetup.bind(this)});
	} else station.subEntities[9].remove();
	// dock 2 - index 8
	if (station._externalDocks.indexOf(2) >= 0) {
		dockmax = 4;
		if (station._externalDocks.indexOf(0) == -1) dockmax -= 1;
		if (station._externalDocks.indexOf(1) == -1) dockmax -= 1;
		eds.$addExternalDock({station:station, position:[0, -3290, 2390], scale:1, dockRange:300, allowLaunch:true, launchSubEntityIndex:(8 - (dockmax - docks)), preDockCallback:this.$preDockSetup.bind(this)});
	} else station.subEntities[8].remove();
	
	// dock 3 - index 7
	if (station._externalDocks.indexOf(3) >= 0) {
		dockmax = 4;
		if (station._externalDocks.indexOf(0) == -1) dockmax -= 1;
		if (station._externalDocks.indexOf(1) == -1) dockmax -= 1;
		if (station._externalDocks.indexOf(2) == -1) dockmax -= 1;
		eds.$addExternalDock({station:station, position:[0, -3290, -2410], scale:1, dockRange:300, allowLaunch:true, launchSubEntityIndex:(7 - (dockmax - docks)), preDockCallback:this.$preDockSetup.bind(this)});
	} else station.subEntities[7].remove();
}
//----------------------------------------------------------------------------------------
// switches docking fees over to the external dock fee
this.$preDockSetup = function (station) {
	if (worldScripts["Docking Fees"]) {
		var df = worldScripts["Docking Fees"];
		delete df._fees["nuit_space_station"];
		df.$addFee("nuit_space_station", { fee: this._externalDockFee, messageKey: "nuit_external_dock_fee" });
	} else {
		var fee = this._externalDockFee;
		if (fee > player.credits) fee = player.credits;
		player.credits -= fee;
		player.addMessageToArrivalReport(expandDescription("[nuit_external_dock_fee]", {
			fee_amt: formatCredits(fee, true, true)
		}));
	}
	this.guiScreenChanged = this.guiScreenChanged_hold;
}
//----------------------------------------------------------------------------------------
// switches docking fees back to standard
// can only do this once all docking processes have finished (rather than using the callback as part of the external dock setup)
this.$postDockSetup = function (station) {
	if (worldScripts["Docking Fees"]) {
		var df = worldScripts["Docking Fees"];
		delete df._fees["nuit_space_station"];
		this.startUpComplete();
	}
} |