| 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; }
 |