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

Expansion HyperCargo

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Extended cargo handling system. Extended cargo handling system.
Identifier oolite.oxp.Thargoid.HyperCargo oolite.oxp.Thargoid.HyperCargo
Title HyperCargo HyperCargo
Category Equipment Equipment
Author Thargoid Thargoid
Version 1.11 1.11
Tags equipment equipment
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/HyperCargo_OXP n/a
Download URL https://wiki.alioth.net/img_auth.php/1/1b/HyperCargo_1.11.oxz n/a
License Creative Commons Attribution - Non-Commercial - Share Alike 3.0 license with clauses - see readme file Creative Commons Attribution - Non-Commercial - Share Alike 3.0 license with clauses - see readme file
File Size n/a
Upload date 1610873243

Documentation

Also read http://wiki.alioth.net/index.php/HyperCargo

HyperCargo v1.11 ReadMe & License.txt

HyperCargo OXP by Thargoid.

The Ships Systems Department of the Aquarian Shipbuilding Corporation introduce their latest development - the HyperCargo system. This is a modernised and updated version of the cargo compression system famously used on larger ships like the Anaconda, now available for any ship (although fitting it to one without a cargo hold is fairly pointless).

Once fitted, it can be accessed by going to the manifest screen (F5 when docked, or F5-F5 when in flight) and then selecting the normal market screen (F8) from there. 

Alternatively (and only for Oolite v1.77 and above) it can be activated via the ship/station interface screen (F4) when docked. For stations with the Commodities Market upgrade, the F5-F8 route is de-activated and only the route via the interface screen can be used to reach the Hypercargo system.

This will allow hold-space cargo to be loaded into the system, and unloaded again back to the normal cargo bay (if sufficient space is available). Whilst running the system continually draws a small amount of energy from the ship, so the recharging of other systems such as shields may be affected.

The system is reliable, although on rare occasions it has been known that cargo stored in it can be lost if a malfunction occurs during unloading or during a witchspace jump. Also should the system become damaged, the stored cargo is invariably lost as the witchspace bubble in which it is stored collapses. It is an "all or nothing" system - the whole of the content of the cargo hold must be stored at once, and it is not possible to restore only part of a stored cargo manifest. As they are stored separately in the ship safe, valuables such as gold, platinum and gem stones are not affected by the HyperCargo system.

The maximum volume of cargo that can be stored depends on the size of the cargo hold of the ship to which the system is fitted, as it must be used as a staging post for loading and unloading the system. Also such cargo is non-transferrable between ships, and is not covered by escape pod insurance policies (as with normal cargo).

Also it should be noted that GalCop have insisted that all HyperCargo systems are scannable by them for illegal merchandise. Anyone caught leaving a GalCop station with illegal material stored in their HyperCargo system will be subject to the same penalties as if the items were stored in their regular cargo hold. It has been rumoured however that on occasions a software hack is available via the underworld on some of the higher-tech but less law abiding worlds which can mask this. Such modifications are deemed illegal by GalCop, and tend to make the systems run less reliably and malfunction more.

Requires v1.74 or later of Oolite. It will not run on older versions.

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

License:

This OXP is released under the Creative Commons Attribution - Non-Commercial - Share Alike 3.0 license with the following clauses:

* Whilst you are free (and encouraged) to re-use any of the scripting, models or texturing in this OXP, the usage must be distinct from that within this OXP. Unique identifiers such as (but not limited to) unique shipdata.plist entity keys, mission variables, script names (this.name), equipment identity strings (EQ_), description list arrays and entity roles must not be re-used without prior agreement. Basically if it's unique or would identify or overwrite anything in the original OXP, then you may not re-use it (for obvious compatibility reasons).
* rebundling of this OXP within another distribution is permitted as long as it is unchanged. The following derivates however are permitted and except from the above:
	* the conversion of files between XML and openStep.
	* the merging of files with other files of the same type from other OXPs.
* The license information (either as this file or merged into a larger one) must be included in the OXP.
* Even though it is not compulsory, if you are re-using any sizable or recognisable piece of this OXP, please let me know :)

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

Instructions:

Unzip the file, and then move the folder "HyperCargo 1.10.oxp" to the AddOns directory of your Oolite installation. Then start the game up and the ships should be added. 

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

Version history:

30/08/2010 - Version 1.00, initial release.
03/09/2010 - Version 1.01, added machinery to the list (oops!). Also added chance of failure on witchspace jumps.
05/09/2010 - Version 1.02, tweaked script to make firearms illegal rather than alloys.
13/02/2011 - Version 1.03, removal of upper limit, to allow running with 1.75
19/02/2011 - Version 1.04, script tweak to change Manifest[""] to manifest[""].
13/04/2012 - Version 1.05, update for compatibility with cim's New Cargoes OXP.
14/04/2012 - Version 1.06, minor script tweak to remove problem with NC start-up if HyperCargo is empty.
22/04/2012 - Version 1.07, update for permits in New Cargoes.
16/05/2012 - Version 1.08, adjustments ready for Oolite 1.77 to cope with equipment taking up cargo space.
25/05/2012 - Version 1.09, removal of a script bug causing special cargo duplication on launch.
25/11/2012 - Version 1.10, added access route via docked Interface (F4) screen to allow for clash with Commodities Marketplace OXP for Oolite 1.77
09/02/2020 - Version 1.11, commodity names for Liquor/Wines and Alien Items (that did't match the ones used in Manifest) corrected, some log messages added
--------------------------------------------------------------

Acknowledgements:

With thanks to Switeck for pointing out the machinery bug, and Okti for the manifest one!

And thanks to cim for preparing the APIs to allow making this OXP compatible with his so simple (and for the commodities calculation code), and Capt Murphy for the bug-report for v1.05/6 and for v1.09 (he's getting almost as good at spotting bugs in this OXP as I seem to be at writing them...).

Equipment

Name Visible Cost [deci-credits] Tech-Level
HyperCargo System yes 120000 13+
HyperCargo System Illicit Hack yes 60000 9+

Ships

This expansion declares no ships.

Models

This expansion declares no models.

Scripts

Path
Config/script.js
this.name				= "HyperCargo";
this.author				= "Thargoid";
this.copyright				= "Creative Commons: attribution, non-commercial, sharealike with clauses - see readme.txt";
this.description			= "Cargo space compression";
this.version				= "1.11";

this.startUp = function()
	{
	this.cargoNameArray = ["food", "textiles", "radioactives", "slaves", "liquor_wines", "luxuries", "narcotics", "computers", "machinery", "alloys", "firearms", "furs", "minerals", "alien_items"];
	this.cargoDisplayNameArray = ["Food", "Textiles", "Radioactives", "Slaves", "Liquor/Wines", "Luxuries", "Narcotics", "Computers", "Machinery", "Alloys", "Firearms", "Furs", "Minerals", "Alien Items"];
	this.storedArray = [0,0,0,0,0,0,0,0,0,0,0,0,0,0]; // the array of stored cargo amounts (don't store gold, platinum or gems)
	this.defaultCommodities = [         
		[ "Food", 0, 0, 19, -2, -2, 6, 1, 1, 0 ],
		[ "Textiles", 0, 0, 20, -1, -1, 10, 3, 3, 0 ],
		[ "Radioactives", 0, 0, 65, -3, -3, 2, 7, 7, 0 ],
		[ "Slaves", 0, 0, 40, -5, -5, 226, 31, 31, 0 ],
		[ "Liquor/Wines", 0, 0, 83, -5, -5, 251, 15, 15, 0 ],
		[ "Luxuries", 0, 0, 196, 8, 8, 54, 3, 3, 0 ],
		[ "Narcotics", 0, 0, 235, 29, 29, 8, 120, 120, 0 ],
		[ "Computers", 0, 0, 154, 14, 14, 56, 3, 3, 0 ],
		[ "Machinery", 0, 0, 117, 6, 6, 40, 7, 7, 0 ],
		[ "Alloys", 0, 0, 78, 1, 1, 17, 31, 31, 0 ],
		[ "Firearms", 0, 0, 124, 13, 13, 29, 7, 7, 0 ],
		[ "Furs", 0, 0, 176, -9, -9, 220, 63, 63, 0 ],
		[ "Minerals", 0, 0, 32, -1, -1, 53, 3, 3, 0 ],
		[ "Alien Items", 0, 0, 53, 15, 0, 0, 7, 0, 0 ]
	];
	this.warningSound = new SoundSource; 
	this.warningSound.sound = "warning.ogg";
	this.warningSound.loop = false;
	
	this.shipDockedWithStation();
	
	if(!missionVariables.hyperCargoFailChance) {missionVariables.hyperCargoFailChance = 0.01;}

	this.ncCheckTimer = new Timer(this, this.checkNCVersion, 1); // check the existence and version of cim's New Cargoes OXP - 1s delay to ensure scripts are loaded if present.
	
	if(!missionVariables.hyperCargoMemory || missionVariables.hyperCargoMemory == "EMPTY") 
		{ // if this is the first run of the OXP, or if there is nothing in storage from the last save game we don't need to restore anything
		log(this.name, "HyperCargo System empty");
		missionVariables.hyperCargoMemory = "EMPTY"; 
		return;
		}
		
	this.storedArray = missionVariables.hyperCargoMemory.split(":");

	let setupCounter = 0 ; // reset the counter
	for(setupCounter = 0;setupCounter<14;setupCounter++)
		{
		log(this.name, "HyperCargo has " + this.storedArray[setupCounter] + "t of " + this.cargoNameArray[setupCounter]);
		this.storedArray[setupCounter] *= 1;  // to swap value from string to number 	
		}
	}

this.checkNCVersion = function()
	{
	this.ncEnabled = false;
	if(!worldScripts.CargoTypeExtension) { return; }
	
	if(!worldScripts.CargoTypeExtension.mergePlayerManifest)
		{
		mission.runScreen({title:"New Cargoes OXP Update Needed", messageKey:"hyperCargo_updateNC"});
		return; 
		}

	this.ncEnabled = true;
	if(!missionVariables.hyperCargoNewCargoes)
		{ missionVariables.hyperCargoNewCargoes = ""; }
			
	}
	
this.unloadCargo = function(suppress)
	{
	if(missionVariables.hyperCargoMemory == "EMPTY")
		{
		player.consoleMessage("HyperCargo is empty", 4);
		return;
		}
	
	if(!suppress && Math.random() < missionVariables.hyperCargoFailChance)
		{
		player.ship.setEquipmentStatus("EQ_HYPERCARGO", "EQUIPMENT_DAMAGED");
		return;
		}

	let cargoCounter = 0 ; // reset the counter
	for(cargoCounter = 0;cargoCounter<14;cargoCounter++)
		{
		this.cargoItem = this.cargoNameArray[cargoCounter];
		log(this.name, "unloading "+String(this.storedArray[cargoCounter]) + "t of " + this.cargoItem);
		manifest[this.cargoItem] += this.storedArray[cargoCounter];
		this.storedArray[cargoCounter] = 0;
		}	

	if(this.ncEnabled && missionVariables.hyperCargoNewCargoes)
		{ 
		worldScripts.CargoTypeExtension.mergePlayerManifest(missionVariables.hyperCargoNewCargoes);
		missionVariables.hyperCargoNewCargoes = null;		
		}
			
	this.stopTimer();
	if (!suppress) { player.consoleMessage("Cargo unloaded from HyperCargo", 4); }
	missionVariables.hyperCargoMemory = "EMPTY";
	}
	
this.transferCargo = function()
	{
	this.subTotal = -50;
	let cargoCounter = 0 ; // reset the counter
	for(cargoCounter = 0;cargoCounter<14;cargoCounter++)
		{
		var commodity = this.defaultCommodities[cargoCounter];
		var price = Math.floor(((commodity[3]+(Math.floor(256*system.scrambledPseudoRandomNumber(23))&commodity[7])+(system.economy*commodity[4]))&255) * 0.4);
		this.cargoItem = this.cargoNameArray[cargoCounter];
		this.subTotal += this.storedArray[cargoCounter] * price; 
		log(this.name, "Transfering "+ String(this.storedArray[cargoCounter]) + "t of " + this.cargoItem + "for Cr" + String(this.storedArray[cargoCounter] * price));
		this.storedArray[cargoCounter] = 0;		
		}	
	
	missionVariables.hyperCargoMemory = "EMPTY";	
	this.stopTimer();	
	if(this.ncEnabled && missionVariables.hyperCargoNewCargoes)
		{ missionVariables.hyperCargoNewCargoes	= null; }

	if((player.credits + this.subTotal) < 0)
		{
		player.credits = 0;
		mission.runScreen({title:"HyperCargo Transfer"});
		mission.addMessageText("\nYour cargo transfer is completed.\n\nHowever even with the payment, your funds do not cover the 50₢ fee and the cargo master is not happy. In lieu of full payment, you are set to work cleaning up the trading floor and shifting the empty cargo pods.");
		clock.addSeconds(Math.random() * 86400);
		}
	else
		{
		player.credits = player.credits + this.subTotal;
		mission.runScreen({title:"HyperCargo Transfer"});
		mission.addMessageText("\nYour cargo transfer is completed.\n\nYour HyperCargo system has been emptied into the station market storage system, in return for a payment of " + this.subTotal + "₢ including fees and charges.");
		}
	}

	
this.loadCargo = function(suppress)
	{
	if(missionVariables.hyperCargoMemory != "EMPTY")
		{
		player.consoleMessage("HyperCargo is already in use", 4);
		return;
		}
		
	missionVariables.hyperCargoMemory = "";
	let loadCounter = 0 ; // reset the counter
	for(loadCounter = 0;loadCounter<14;loadCounter++)
		{
		this.cargoItem = this.cargoNameArray[loadCounter];
		this.storedArray[loadCounter] = manifest[this.cargoItem];
		log(this.name, "Loading "+ String(manifest[this.cargoItem]) + "t of " + this.cargoItem);
		missionVariables.hyperCargoMemory = missionVariables.hyperCargoMemory + manifest[this.cargoItem] + ":";
		manifest[this.cargoItem] = 0;
		}	

	if(this.ncEnabled)
		{ missionVariables.hyperCargoNewCargoes = worldScripts.CargoTypeExtension.suspendPlayerManifest(); }
		
	this.startTimer();
	if(!suppress) { player.consoleMessage("Cargo loaded to HyperCargo", 4); }
	}

this.guiScreenChanged = function(to, from)
	{
	if(to != "GUI_SCREEN_MARKET" || from != "GUI_SCREEN_MANIFEST" || player.ship.equipmentStatus("EQ_HYPERCARGO") != "EQUIPMENT_OK")
		{ // access only from manifest to market if we have the equipment installed
		return;
		} 
	this.activateHC();	
	}

this.activateHC = function()	
	{
	if(missionVariables.hyperCargoMemory == "EMPTY")
		{
		this.goldTons = Math.ceil((manifest["gold"] - 499) / 1000);
		if(this.goldTons < 0) {this.goldTons = 0;};

		this.platinumTons = Math.ceil((manifest["platinum"] - 499) / 1000);
		if(this.platinumTons < 0) {this.platinumTons = 0;};

		this.gemsTons = Math.ceil((manifest["gemStones"] - 499999) / 1000000);
		if(this.gemsTons < 0) {this.gemsTons = 0;};

		if(player.ship.cargoSpaceUsed - (this.goldTons + this.platinumTons + this.gemsTons) == 0)
			{ mission.runScreen({title:"HyperCargo Readout", messageKey:"hyperCargo_emptyNoLoad"}); }
		else
			{ mission.runScreen({title:"HyperCargo Readout", messageKey:"hyperCargo_emptyLoad", choicesKey:"hyperCargo_loadChoice"}, this.choice); }
		return;
		}
	else
		{
		this.totalCargo = 0
		let unloadCounter = 0 ; // reset the counter
		for(unloadCounter = 0;unloadCounter<14;unloadCounter++)
			{ this.totalCargo += this.storedArray[unloadCounter]; }
		
		if(this.totalCargo > player.ship.cargoSpaceCapacity)
			{
			if(player.ship.docked && player.ship.dockedStation.isMainStation)
				{
				mission.runScreen({title:"HyperCargo Readout",choicesKey:"hyperCargo_transferChoice"}, this.choice);
				this.addList();
				mission.addMessageText("\nYour cargo hold is no longer large enough to deactivate the system.\nFor a fee of 50₢ the station market can accept and sell the load.\nDo you wish to proceed?");
				}
			else
				{
				mission.runScreen({title:"HyperCargo Readout", messageKey:"hyperCargo_unloadHeader"});
				this.addList();
				mission.addMessageText("\nYour cargo hold is no longer large enough to deactivate the system.\nPlease visit the system main station for cargo sales assistance.");
				}
			return;	
			}						
			
		if(this.totalCargo > player.ship.cargoSpaceAvailable)
			{
			mission.runScreen({title:"HyperCargo Readout", messageKey:"hyperCargo_unloadHeader"});
			this.addList();
			mission.addMessageText("\nAt present your cargo hold has insufficient space to deactivate the system.");
			return;
			}						
		else
			{
			mission.runScreen({title:"HyperCargo Readout", messageKey:"hyperCargo_unloadHeader",choicesKey:"hyperCargo_unloadChoice"}, this.choice);
			this.addList();
			mission.addMessageText("\nDo you wish to deactivate the system?");
			return;
			}
		}
	}
	
this.addList = function()
	{
	let listCounter = 0 ; // reset the counter
	for(listCounter = 0;listCounter<14;listCounter++)
		{
		this.cargoItem = this.cargoDisplayNameArray[listCounter];
		this.cargoAmount = this.storedArray[listCounter];
		this.messageText = this.cargoItem + " : " + this.cargoAmount + "t.";
		mission.addMessageText(this.messageText);
		}
	}
	
this.choice = function(choice)
	{
	switch(choice)
		{
		case "HYPERCARGO_1_LOAD_ACCEPT":
			{
			this.loadCargo(false);
			break;
			}
		case "HYPERCARGO_1_UNLOAD_ACCEPT":
			{
			this.unloadCargo(false);
			break;
			}	
		case "HYPERCARGO_1_TRANSFER_ACCEPT":
			{
			this.transferCargo();
			break;
			}
		}
	}
	
this.shipExitedWitchspace = function()
	{
	if(player.ship.equipmentStatus("EQ_HYPERCARGO") == "EQUIPMENT_OK" && (Math.random() < missionVariables.hyperCargoFailChance))
		{
		player.ship.setEquipmentStatus("EQ_HYPERCARGO", "EQUIPMENT_DAMAGED");
		return;
		}
	}
	
this.equipmentDamaged = function(equipment)
	{
	if(equipment == "EQ_HYPERCARGO")
		{
		if(missionVariables.hyperCargoMemory == "EMPTY")
			{ player.consoleMessage("HyperCargo system malfunction detected", 6); }
		else
			{ player.consoleMessage("HyperCargo malfunction - stored cargo has been lost!", 6); }
		this.warningSound.play();
		this.resetCargo();	
		}
	}
	
this.playerBoughtNewShip = this.shipLaunchedEscapePod = this.resetCargo = function()
	{
	this.checkNCVersion();
	this.stopTimer();
	this.storedArray = [0,0,0,0,0,0,0,0,0,0,0,0,0,0];
	missionVariables.hyperCargoMemory = "EMPTY";
	missionVariables.hyperCargoFailChance = 0.01;
	
	if(this.ncEnabled)
		{ 	missionVariables.hyperCargoNewCargoes = ""; }
	}

this.playerBoughtEquipment = function(equipment)
	{
	switch(equipment)
		{
		case "EQ_HYPERCARGO":
			{
			this.resetCargo();
			break;
			}
		case "EQ_HYPERCARGO_HACK":
			{
			missionVariables.hyperCargoFailChance = 0.05;
			player.ship.removeEquipment("EQ_HYPERCARGO_HACK");
			break;
			}
		}
	}
	
this.shipLaunchedFromStation = function(station)
	{
	if(player.ship.equipmentStatus("EQ_HYPERCARGO") == "EQUIPMENT_OK" && missionVariables.hyperCargoMemory != "EMPTY")
		{	
		this.startTimer();
		if(missionVariables.hyperCargoFailChance == 0.01 && station.isMainStation)
			{ 
			if(this.ncEnabled)
				{ this.checkPermits(); }
			else
				{ player.bounty += this.storedArray[3] + (2 * this.storedArray[6]) + this.storedArray[10]; }
			}
		}
	}

this.checkPermits = function()
	{
	this.penalty = this.storedArray[3] + (2 * this.storedArray[6]) + this.storedArray[10];

	this.tempNC = worldScripts.CargoTypeExtension.suspendPlayerManifest();
	worldScripts.CargoTypeExtension.restorePlayerManifest(missionVariables.hyperCargoNewCargoes);
	
	this.specialCargoesCarried = worldScripts.CargoTypeExtension.specialCargoesCarried();
	if(this.specialCargoesCarried.length === 0)
		{ 
		worldScripts.CargoTypeExtension.restorePlayerManifest(this.tempNC)
		return;
		}

	let checkCounter = 0 ; // reset the counter
	for(checkCounter = 0;checkCounter<this.specialCargoesCarried.length;checkCounter++)
		{
		this.checkCargo = worldScripts.CargoTypeExtension.cargoDefinition(this.specialCargoesCarried[checkCounter],"genericType");
		if(this.checkCargo === "slaves" || this.checkCargo === "narcotics" || this.checkCargo === "firearms")
			{
			this.penalty += worldScripts.CargoTypeExtension.hasSpecialCargo(this.specialCargoesCarried[checkCounter]) * worldScripts.CargoTypeExtension.exportPermitLevel(this.specialCargoesCarried[checkCounter], worldScripts.CargoTypeExtension.hasSpecialCargo(this.specialCargoesCarried[checkCounter]));
			}
		}

	worldScripts.CargoTypeExtension.restorePlayerManifest(this.tempNC)
	if(this.penalty > 0) { player.bounty += this.penalty; }
	}
	
this.shipWillDockWithStation = this.stopTimer = function(station)
	{
	if(this.energyDrainTimer && this.energyDrainTimer.isRunning)
		{ this.energyDrainTimer.stop(); }
	}

this.equipmentRepaired = function(equipment)
	{
	if(equipment && equipment === "EQ_HYPERCARGO")
		{ this.shipDockedWithStation(); }
	}	
	
this.shipDockedWithStation = function()
	{
	if (0 >= oolite.compareVersion("1.77") && player.ship.docked && player.ship.equipmentStatus("EQ_HYPERCARGO") === "EQUIPMENT_OK")
		{
		player.ship.dockedStation.setInterface("Hypercargo",
			{ title: "Access Hypercargo",
			category: "Ship",
			summary: "Accesses the Hypercargo system.",
			callback: this.activateHC.bind(this) });
		}
	}	
	
this.startTimer = function()
	{
	if(player.ship.docked)
		{ return; }
	if(this.energyDrainTimer)
		{ this.energyDrainTimer.start() }
	else
		{ this.energyDrainTimer = new Timer(this, this.drainEnergy,0,0.5) }
	}
	
this.drainEnergy = function()
	{ player.ship.energy -= 0.5; }