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

Expansion Manifest Scanner

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description The manifest scanner allows you to scan a ships cargo manifest and display it in a MFD when activated. The manifest scanner allows you to scan a ships cargo manifest and display it in a MFD when activated.
Identifier oolite.oxp.stormrider.manifestScanner oolite.oxp.stormrider.manifestScanner
Title Manifest Scanner Manifest Scanner
Category Equipment Equipment
Author Stormrider Stormrider
Version 1.3.2 1.3.2
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/Manifest_Scanner n/a
Download URL https://wiki.alioth.net/img_auth.php/8/8c/Manifest_Scanner_1.3.2.oxz http://wiki.alioth.net/img_auth.php/5/5f/ManifestScanner_1.3.2.oxz
License CC BY-NC-SA 4.0 CC BY-NC-SA 4.0
File Size n/a
Upload date 1610873357

Documentation

Also read http://wiki.alioth.net/index.php/Manifest%20Scanner

Equipment

Name Visible Cost [deci-credits] Tech-Level
Manifest Scanner yes 32000 8+
Remove Manifest Scanner no 200 4+

Ships

This expansion declares no ships.

Models

This expansion declares no models.

Scripts

Path
Scripts/ManifestScanner.js
//			~~~I STRONGLY encourage the modification and development of this free software by anyone to meet your needs, I only ask that you give me credit for the original work. Thanks and enjoy.~~~
"use strict";
this.author      = "Morgan Orr"; 
this.copyright   = "� 2011-2017 Morgan Orr."; 
this.licence = "CC-BY-SA 4.0";
this.version     = "1.3.2"; 



/* version 1.2 modifed by Nick Rogers (phkb)
 - made scan take a few seconds, rather than being instantaneous (makes it feel more real)
 - added manual/active scan modes (so you don't have to prime the equipment and activate a scan)
 - fixed issue with MFD where ships with more that 8 manifest types were not being displayed correctly. it was working on the basis of having 9 lines
   whereas there were only 8 lines available
 - if ship has more than 16 items, MFD will switch to a 3 column version. (Hopefully the chances of a ship needing 4 columns is remote!)
 - removed the framecallback for the scan process, reused it to check for lost target via wormholes
 - some general code tiding and refactoring.
*/


this.name        = "ManifestScanner";
this.description = "Scan a ship's manifest and displays results in a MFD";

this._scanTimer = null;
this._scanTime = 5;
this._scanMemory = [];
this.$manscanLst = false;
this.$manscanMsg =""; //message for mfd
this._scanMode = 0; // 0 = manual scanning, 1 = active scanning
this._loadedPrevScan = false;
this._validScanClasses = ["CLASS_NEUTRAL", "CLASS_POLICE", "CLASS_MILITARY"];

//-------------------------------------------------------------------------------------------------------------
this.startUp = function() {
	this.$manscanlogging = true;
}

//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function() {
	if (missionVariables.ManifestScanner_ScanMode != null) this._scanMode = missionVariables.ManifestScanner_ScanMode;
}

//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function() {
	missionVariables.ManifestScanner_ScanMode = this._scanMode;
}

//-------------------------------------------------------------------------------------------------------------
//update the mfd message and start a framecallback on launch
this.shipWillLaunchFromStation = function() {
	this.$manscanmfdInfo();
	if (!this.$manscanmfd)
		this.$manscanmfd = addFrameCallback(this.$checkForLostTarget.bind(this));
	
	player.ship.setMultiFunctionText("ManifestScanner", ""+this.$manscanMsg+"");
}

//-------------------------------------------------------------------------------------------------------------
//remove framecallback on docking or death
this.shipWillDockWithStation = function() {
	if (this._scanTimer && this._scanTimer.isRunning) this._scanTimer.stop();
	this.$removeFCB();
}

//-------------------------------------------------------------------------------------------------------------
this.shipDied = function(whom, why) {
	this.$removeFCB();
}

//-------------------------------------------------------------------------------------------------------------
this.activated = function() { //try to enable scanner as primed eq
	var w = worldScripts.ManifestScanner;
	if (this._scanTimer == null || this._scanTimer.isRunning == false) {
		if (w.$manscanMsg.indexOf("Invalid target") != -1 || 
			w.$manscanMsg.indexOf("No target") != -1 || 
			w.$manscanMsg.indexOf("Target lost") != -1 ||
			w.$manscanMsg.indexOf("Unable to scan") != -1) return;

		w.$manscanLst = true;
		w.$manscanmfdInfo(0);
		
		player.ship.setMultiFunctionText("ManifestScanner", w.$manscanMsg+"\n...scanning...");
			
		this._scanTimer = new Timer(this, this.$runScan.bind(this), this._scanTime, 0);
	} else if(this._scanTimer && this._scanTimer.isRunning) {
		this._scanTimer.stop();
		player.ship.setMultiFunctionText("ManifestScanner", w.$manscanMsg);
	}
}

//-------------------------------------------------------------------------------------------------------------
this.mode = function() { //attempt to make scanner update with "n" key
	var w = worldScripts.ManifestScanner;

	if (w._scanMode == 0) {
		w._scanMode = 1;
		player.consoleMessage("Manifest Scanner Active Scan Mode");
	} else {
		w._scanMode = 0;
		w._scanMemory = []; w.$manscanmfdInfo(0); if(w.$manscanlogging) log(w.name,w.name+" : Clear scan memory") // rustem // 1 method
		player.consoleMessage("Manifest Scanner Manual Scan Mode");
	}
}

//-------------------------------------------------------------------------------------------------------------
this.shipExitedWitchspace = function() {
	this._scanMemory = [];
	this.$manscanmfdInfo(0);
}

//-------------------------------------------------------------------------------------------------------------
this.shipEnteredWitchspace = function() {
	if (this._scanTimer && this._scanTimer.isRunning) this._scanTimer.stop();
	this.$manscanMsg = "Manifest Scanner: No target";
	this.$manscanmfdInfo();
	player.ship.setMultiFunctionText("ManifestScanner", ""+this.$manscanMsg+""); 
}	

//-------------------------------------------------------------------------------------------------------------
// update when new target aquired
this.shipTargetAcquired = function(target) {
	if (this._scanTimer && this._scanTimer.isRunning) this._scanTimer.stop();
	this.$manscanmfdInfo(0);
	//if(this.$manscanlogging) log(this.name,this.name+"Target? : "+player.ship.target)
	player.ship.setMultiFunctionText("ManifestScanner", ""+this.$manscanMsg+"");
	// if active scanning is enabled, run the scan as soon as we have a target
	if (this._scanMode == 1 && this._loadedPrevScan == false) {
		if (target.isShip && this._validScanClasses.indexOf(target.scanClass) >= 0) {
			this.activated();
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
//remove list when target lost ~~~ version 0.2.3 attempt to turn off so must be activated every time a new target is aquired
this.shipTargetLost = function(target) {
	if (this._scanTimer && this._scanTimer.isRunning) this._scanTimer.stop();
	this.$manscanMsg = "Manifest Scanner: Target lost";
	player.ship.setMultiFunctionText("ManifestScanner", ""+this.$manscanMsg+""); 
}

//-------------------------------------------------------------------------------------------------------------
// removes the frame callback
this.$removeFCB = function() {
	if (this.$manscanmfd) {
		removeFrameCallback(this.$manscanmfd);
		delete this.$manscanmfd;
	}
}

//-------------------------------------------------------------------------------------------------------------
// runs the manifest scan and updates the MFD
this.$runScan = function() {
	this.$manscanLst = true;
	this.$manscanmfdInfo(1);
	player.ship.setMultiFunctionText("ManifestScanner", ""+this.$manscanMsg+"");
}

//-------------------------------------------------------------------------------------------------------------
// checks to see if the players current target has disappeared (eg into a wormhole)
this.$checkForLostTarget = function() {
	if (player.ship.target == null && this.$manscanMsg.indexOf("Manifest Scanner:") == -1) this.shipTargetLost();
}

//-------------------------------------------------------------------------------------------------------------
//display targets manifest in a MFD
this.$manscanmfdInfo = function(repType) {
	
	// rep type 0 = cargo capacity only
	// rep type 1 = all data

	var p = player.ship;
	if (!p || !p.isValid || p.equipmentStatus('EQ_MANIF_SCANNER') !== 'EQUIPMENT_OK') return;
	var target = "";
	var t = p.target;

	this._loadedPrevScan = false;
	if (t != null) {
		var prevScan = worldScripts.ManifestScanner.$findShipScan(t);
		if (prevScan != "") {
			this.$manscanMsg = prevScan;
			this._loadedPrevScan = true; 
			if(this.$manscanlogging) log(this.name,this.name+" : will loaded prevScan for "+t.displayName+"["+t.cargoSpaceUsed+"]"); // rustem
			return;
		}
	}

	var tdn = "";
	var message = "Manifest Scanner: ";
	if (!t) message += "No target";
	if (t && t.isValid) {
		if (this._validScanClasses.indexOf(t.scanClass) == -1) { 
			message += "Invalid target";
		} else if(t.isDerelict) {
			message += "Unable to scan\nNo power to ship systems.\nRemote query of manifest failed.";
		} else {
			tdn = t.displayName+"\nCargo " + t.cargoSpaceUsed + " t (" + t.cargoSpaceCapacity + " t):";

			if (t.cargoSpaceCapacity == 0 || t.cargoSpaceUsed == 0) {
				tdn += "\n  None.";
				// there is no capacity, or nothing stored, so no need to scan - tell calling routine to skip the scan process
				this._loadedPrevScan = true;
			}
			
			if (t.cargoSpaceCapacity > 0 && repType == 1) {
				var lst = t.cargoList;
				if (lst.length === 0) tdn += "\n  None.";

				if(this.$manscanLst) {
					var units = new Array();
					for (var i = 0; i < lst.length; i++) {
						var l = lst[i];
						units.push(l.quantity + " " + String.fromCharCode(215) + " "+ l.displayName);
					} 
					var columns = Math.ceil(units.length / 8);
					var colWidths = [15, 7.5, 7]; // 3rd column width is 7 - we want Oolite to squeeze the font in this instance
					var colWidth = colWidths[columns - 1];
					for (var i = 0; i < 8; i++) {
						var line = "";
						
						if (i < units.length) line = "\n" + this.$padTextRight(" " + units[i], colWidth);
						if ((i + 8) < units.length) line += this.$padTextRight(units[i+8], colWidth);
						if ((i + 16) < units.length) line += this.$padTextRight(units[i+8], colWidth);
						
						if (line != "") tdn += line;
					}
				}
			}
			message = tdn;
		}
	}
	this.$manscanMsg = message;
	if (t && t.isValid && t.isShip && t.isPiloted && repType == 1) worldScripts.ManifestScanner.$addShipScan(t, message);
}

//-------------------------------------------------------------------------------------------------------------
// adds or updates the scan for a ship
this.$addShipScan = function(shp, dta) {
	var index = null;
	var found = false;
	var shipKey = shp.displayName + shp.dataKey + shp.entityPersonality + shp.primaryRole; // rustem / 2 method: + shp.cargoSpaceUsed
	for (var i = 0; i < this._scanMemory.length; i++) {
		if (this._scanMemory[i].ship == shipKey) { // rustem / 3 method: add check cargoSpaceUsed + add replace scanData
			index = i;													// found an any data
			if (this._scanMemory[i].shipCSU == shp.cargoSpaceUsed) { 	// found a last correct data
				found = true;
				this._scanMemory[i].scanCSU = shp.cargoSpaceUsed;
				this._scanMemory[i].scanData = dta;
				break;
			}
		}
	}
	if (found == false) {
		if (index == null) {		// rustem
			this._scanMemory.push({ship:shipKey, scanCSU:shp.cargoSpaceUsed, scanData:dta});
			if(this.$manscanlogging) log(this.name,this.name+" : push data for "+shp.displayName+"["+shp.cargoSpaceUsed+"]");
		} else {
			//index = index+1;
			this._scanMemory.splice(index, 1, {ship:shipKey, scanCSU:shp.cargoSpaceUsed, scanData:dta});
			if(this.$manscanlogging) log(this.name,this.name+" : replace["+index+"] data for "+shp.displayName+"["+shp.cargoSpaceUsed+"]");			
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
// checks the scan memory for a scan for this ship
this.$findShipScan = function(shp) {
	var shipKey = shp.displayName + shp.dataKey + shp.entityPersonality + shp.primaryRole; // rustem / 2 method: + shp.cargoSpaceUsed
	for (var i = 0; i < this._scanMemory.length; i++) {
		if (this._scanMemory[i].ship == shipKey && this._scanMemory[i].scanCSU == shp.cargoSpaceUsed) return this._scanMemory[i].scanData; // rustem / 3 method
	}
	return "";
}

//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextRight = function(currentText, desiredLength, leftSwitch) {
	if (currentText == null) currentText = "";
	var hairSpace = String.fromCharCode(31);
	var ellip = "…";
	var currentLength = defaultFont.measureString(currentText);
	var hairSpaceLength = defaultFont.measureString(hairSpace);
	// calculate number needed to fill remaining length
	var padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
	if (padsNeeded < 1)	{
		// text is too long for column, so start pulling characters off
		var tmp = currentText;
		do {
			tmp = tmp.substring(0, tmp.length - 2) + ellip;
			if (tmp == ellip) break;
		} while (defaultFont.measureString(tmp) > desiredLength);
		currentLength = defaultFont.measureString(tmp);
		padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
		currentText = tmp;
	}
	// quick way of generating a repeated string of that number
	if (!leftSwitch || leftSwitch == false) {
		return currentText + new Array(padsNeeded).join(hairSpace);
	} else {
		return new Array(padsNeeded).join(hairSpace) + currentText;
	}
}
Scripts/ManifestScannerEq.js
//			~~~I STRONGLY encourage the modification and development of this free software by anyone to meet your needs, I only ask that you give me credit for the original work. Thanks and enjoy.~~~
"use strict";
this.author      = "Morgan Orr"; 
this.copyright   = "� 2011-2017 Morgan Orr."; 
this.licence = "CC-BY-SA 4.0";
this.version     = "1.3.2"; 


/* version 1.2 modifed by Nick Rogers (phkb)
 - Cleaned up unnecessary lines in equipment.plist
 - Expanded text displayed if the player is discovered with a manifest scanner while doing a renovation.
 - included gov type 4 in all government checks
*/


this.name        = "ManifestScannerEq";
this.description = "Equipment control script for the manifest scanner";

//restrict from mainstations communist-corprate systems
this.allowAwardEquipment = function(equipment, ship, context) {
	var p = player.ship;
	var stn = p.dockedStation;
	if (context == "purchase" && system.government >= 4 && stn.allegiance == "galcop") {
		return false;
	} else {
		return true;
	}
}

this.playerBoughtEquipment = function(equipment) {
	var p = player.ship;
	var stn = p.dockedStation;
	if( equipment === "EQ_MANIF_SCANNERX" ) {
		p.removeEquipment("EQ_MANIF_SCANNERX");
		p.removeEquipment("EQ_MANIF_SCANNER");
		var info = EquipmentInfo.infoForKey("EQ_MANIF_SCANNER");
		var refund = parseInt(((info.price / 10) * p.dockedStation.equipmentPriceFactor) * 0.9218);
		
		player.credits += refund; //2950
	}

	//Remove and fine if techies at mainstation find it in communist-corprate systems 
	if (equipment === "EQ_RENOVATION" && 
		system.government >= 4 && 
		stn.allegiance == "galcop" && 
		(p.equipmentStatus("EQ_MANIF_SCANNER") == "EQUIPMENT_OK" || p.equipmentStatus("EQ_MANIF_SCANNER") == "EQUIPMENT_DAMAGED")) {

		this._scannerRemove = true;
		mission.runScreen({
			title: "Suspicious Activity", 
			message: "It appears that some of your equipment has been tampered with.", 
			model:"station"}
		);
	}
}

this.missionScreenOpportunity= function() {
	if(this._scannerRemove) {
    	this._scannerRemove = false;
        mission.runScreen({
			title: "Equipment Confiscated", 
			message: "Your Manifest Scanner has been confiscated as per GalCop regulation GC-149874-2 which states:" + 
			"\n\n'Devices designed to scan a ship's manifest while in space, operating in unauthorised vessels, are deemed to be illegal. " + 
			"Should such a device be discovered on a ship by a GalCop official in any capacity (be it law enforcement or engineering), it will be removed and destroyed.'" + 
			"\n\nWe would normally issue a fine for this offence, but decided that a warning was sufficient. Please take care to obey GalCop laws in future.", 
			model: "police"
		});
		player.ship.removeEquipment("EQ_MANIF_SCANNER");
    }
}