Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion SellAll

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Sell all cargo in Interfaces and can sell to an alternative cutomer if the market is full. Sell all cargo in Interfaces and can sell to an alternative cutomer if the market is full.
Identifier oolite.oxp.Norby.SellAll oolite.oxp.Norby.SellAll
Title SellAll SellAll
Category Mechanics Mechanics
Author Norby Norby
Version 1.29 1.29
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/SellAll_OXP n/a
Download URL https://wiki.alioth.net/img_auth.php/3/33/SellAll_1.29.oxz n/a
License CC BY-NC-SA 4.0 CC BY-NC-SA 4.0
File Size n/a
Upload date 1610873264

Documentation

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

SellAll readme.txt

Sell All OXP

You can sell all of your cargo under the "Sell all cargo or find an alternative customer" item in Interfaces (F4) screen.

The market capacity usually limited to 127t for each cargo type. If you have more from something than the current free space in the current station then you will find an Alternative Customer here who can buy your unsellable cargo, but pay very low prices only (below the half), less if you want to sell more.
Moreover sometimes you get conned or a few bounty to your head, more if you sell more.

In stations with custom markets will buy all of your cargo instead of the excess only due to calculating the exact market limits are complicated since Oolite 1.81. You still can sell what you can in the F8 screen then look into the interfaces when you have unsellable cargo to sell the excess only.


If you prefer the original limited markets only then change the $SellAllLimit variable to true and your chance for a customer will be reduced to zero.

Can not sell custom cargo types added by OXPs.
Incompatible with Commodity Markets OXP, suggested to use MarketObserver OXP with the included mO-Commodity_Markets to get similar different buy and sell prices.


Dependencies:
Oolite v1.77 or later.
BGS OXP from http://wiki.alioth.net/index.php/BGS if you want to see nice background on the Alternative Customer screen.
MarketObserver OXP if you use custom HUD to fix possible misplaced market messages.

Instructions:
Unzip the file, and then move the folder named ".oxp" into the AddOns directory of your Oolite installation.
Hold down the Shift key when you start the game first time until the splash screen appear.

License:
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License version 4.0.
If you are re-using any piece of this OXP, please let me know by sending an e-mail to norbylite@gmail.com.

Changelog:
 2015.10.18. v1.29 Fixed for Kiota stations.
 2015.10.05. v1.28 Fixed for stations with custom markets since Oolite 1.81.
 2015.10.05. v1.27 A fix for Rock Hermits, thanks to diagoras.
 2015.09.15. v1.26 Compatible with Smugglers OXP.
 2015.08.10. v1.25 The "Sell all" function moved into the Interfaces for Oolite 1.82.
 2013.09.07. v1.24 Better messages, thanks Cody!
 2013.09.06. v1.23 Warning sound when you must watch your back.
 2013.09.06. v1.22 Get conned or bounty when sold alternatively (thanks for the ideas to Cody and Smivs).
 2013.09.05. v1.21 Compatibility fix for mO-Commodity_Markets.
 2013.09.04. v1.2  Alternative Customer added.
                   Compatible with AI Trading Assistant OXP.
 2013.09.04. v1.1  Profit displayed with MarketObserver OXP.
                   Markets limitable to 127t with $SellAllLimit127t.
                   Sell sound added.
 2013.09.04. v1.0  First version to satisfy the request in this topic: http://aegidian.org/bb/viewtopic.php?f=2&t=15317

Equipment

This expansion declares no equipment.

Ships

This expansion declares no ships.

Models

This expansion declares no models.

Scripts

Path
Scripts/sellall.js
"use strict";
this.name        = "sellall";
this.author      = "Norby";
this.copyright   = "2013 Norbert Nagy";
this.licence     = "CC BY-NC-SA 4.0";
this.description = "Sell all cargo with one keypress, sometimes over 127t also for less than half price.";

//customizable properties
this.$SellAllHowManyF8 = 1; //How many additional F8 keypress initiate sell all in the market screen, minimum 1.
this.$SellAllLimit = false; //can limit markets to the original capacity

//internal properties, should not touch
this.$SellAllCargoTypes = ["food", "textiles", "radioactives", "slaves", "liquor_wines", "luxuries",
	"narcotics", "computers", "machinery", "alloys", "firearms", "furs", "minerals",
	"gold", "platinum", "gem_stones", "alien_items"];
this.$SellAllF8Counter = 0; //F8 press counter
this.$SellAllSound = null; //sell soundsource
this.$SellAllSound2 = null; //warning soundsource
this.$SellAllSound3 = null; //conned soundsource
this.$SellAllPressTimer = null; //delayed message

this.startUp = function() {
	this.$SellAllF8Counter = 0;
	this.$SellAllSound = new SoundSource;
	if( worldScripts["BGS-M"] ) {
		this.$SellAllSound.sound = "bgs-c_sell.ogg";  //bgs sell sound
		this.$SellAllBG = "bgs-i_market.png";
	} else {
		this.$SellAllSound.sound = "sell.ogg"; //sell sound
		if(worldScripts["Better Screens"]) this.$SellAllBG = "bs-base-bg.png";
		else this.$SellAllBG = "";
	}
	this.$SellAllSound.loop = false;
	this.$SellAllSound.repeatCount = 1;
	this.$SellAllSound2 = new SoundSource;
	this.$SellAllSound2.sound = "warning.ogg"; //warning sound (original, fit better here than bgs warning)
	this.$SellAllSound2.loop = false;
	this.$SellAllSound2.repeatCount = 1;
	this.$SellAllSound3 = new SoundSource;
	this.$SellAllSound3.sound = "boop.ogg"; //conned sound (original, fit better here than bgs boop)
	this.$SellAllSound3.loop = false;
	this.$SellAllSound3.repeatCount = 1;
}

this.startUpComplete = function() {
	var station = system.mainStation;
	if( player.ship.docked ) station = player.ship.dockedStation;
	this.shipDockedWithStation(station);//to set interface
}

//world script events
/* removed to be compatible with Oolite 1.82 where F8F8 is used in the core
this.guiScreenWillChange = function(to, from) {
	if( player.ship.docked && to == "GUI_SCREEN_MARKET"
		&& this.$SellAllF8Counter == this.$SellAllHowManyF8 - 1 ) { //next F8 will sell
		var c = this.$SellAllCargoTypes; //no message if no cargo on board
		var empty = true;
		for( var i = 0; i < c.length; i++ ) {
			if( player.ship.manifest[c[i]] > 0) {
				empty = false;
				i = c.length;
			}
		}
		if(!empty) this.$SellAllPressTimer = new Timer(this, this.SellAll_PressTimed, 0.05, 0);
	}
	if( player.ship.docked && to == "GUI_SCREEN_MARKET" && from == "GUI_SCREEN_MARKET" ) {
		this.$SellAllF8Counter++;
		if( this.$SellAllF8Counter >= this.$SellAllHowManyF8 ) {
			this.$SellAllF8Counter = 0;
			this.SellAll_Cargo();
			if( this.$SellAllPressTimer ) { //to avoid press F8 message
				this.$SellAllPressTimer.stop();
				delete this.$SellAllPressTimer;
			}
		}
	} else this.$SellAllF8Counter = 0;
}
*/

this.shipDockedWithStation = function(station)
{
	this.$SellAllF8Counter = 0;
	station.setInterface("SellAll-bm",{
		title: "Sell all cargo or find an alternative customer",
		category: "Commerce",
		summary: "Try to sell your cargo here if the market is full.",
		callback: this.SellAll_Interface.bind(this)
		});
}


//SellAll methods
this.SellAll_Cargo = function() {
	var c = this.$SellAllCargoTypes;
	var mo = worldScripts["market_observer"];
	var mc = worldScripts["mo-commodity_markets"];
	var station = system.mainStation;
	if( player.ship.docked ) station = player.ship.dockedStation;
	var max = this.SellAll_GetCapacity(station);
	var p = 0;
	var profit = 0;
	var tc = 0;
	var marketfull = false;
	for( var i = 0; i < c.length; i++ ) {
		var q = player.ship.manifest[c[i]];
		var sq = station.market[c[i]].quantity;
		var rs = max - sq;
		if( q > rs ) {
			q = rs;
			marketfull = true;
		}
		var pr = station.market[c[i]].price/10;
		if( q > 0 ) {
			var cr = q * pr; //cargo cost
			tc += cr;
			station.setMarketQuantity(c[i], Math.min(max, sq + q));
			player.ship.manifest[c[i]] -= q;
			var pf = 1;
			if(mc && mc.$priceFactor) {
				var id = mc.$commodities.indexOf(c[i]);
				if( id > -1 ) pf = 2*(mc.$priceFactor[id]-1)+1; //4-10% more
			}
			if( mo ) {
				var b = mo.$buyLog[mo.$commodities.indexOf(c[i])];
				if( b && b[0] ) p = q * (pr - pf * b[0][1] / 10);//can missing from the buyLog if scooped
				else p = cr;
				profit += p;
			}
			this.SellAll_Notify(c[i], q, pr);
			log("SellAll", "Sell "+q+" "+c[i]+" at "+pr+"cr = "+cr+"cr profit:"+p);
		}
	}
	var msg = "Your cargo space is empty.";
	if( tc > 0 ) {
		tc = Math.round( tc * 10 ) / 10;
		player.credits += tc;
		msg = "You get "+formatCredits(tc, true, true );
		if( mo ) msg+=", profit: "+formatCredits(Math.round(profit*10)/10, true, true );
		this.$SellAllSound.play();
	} else if( marketfull ) msg = "You cannot sell more, the market is full.";
	log("SellAll", msg);
	player.consoleMessage(msg, 10);
	if( mo ) mo.$printValues("                              "+msg+"\n\n"); //refresh market screen
}

this.SellAll_Interface = function() {
	var sdm = worldScripts.Smugglers_DockMaster;
	if ( sdm ) {
		var l = player.ship.manifest.list;
		var m = "";
		var ml = 0;
		for( var i = 0; i < l.length; i++ ) {
			var check = sdm.$getTotalRelabelled(l[i].commodity);
			if( check > 0 && ml < 20 ) { //max. 20 lines to fit into the screen
      // this means there is "check" number of tons of "commodity_name" that isn't really "commodity_name" - it's something else
      // you should skip these units from being sold
				m += "You have "+check+""+l[i].unit+" relabeled "
					+l[i].displayName+".\n";
				ml++;
			}
		}
		if( ml > 0 ) {
			mission.runScreen({
				title: "Relabeled cargo",
				message: m+"\nYou must not hold any relabeled cargo "
					+"to sell all of your cargo.",
				background: this.$SellAllBG,
				screenID: "sellall",
				exitScreen: "GUI_SCREEN_INTERFACES",
				choices: {"_0" : "OK"}
			},function(choice) {
				if(choice == "_0") {
					//exit
				}
			});
			return;
		}
	}
	
	var c = this.$SellAllCargoTypes;
	var station = system.mainStation;
	if( player.ship.docked ) station = player.ship.dockedStation;
	var max = this.SellAll_GetCapacity(station);
	var rem = 0;
	for( var i = 0; i < c.length; i++ ) {
		var remq = 0;
		var q = player.ship.manifest[c[i]];
		var rs = 0;
		if( max > 0 ) rs = max - station.market[c[i]].quantity;
		if( q > rs ) {
			remq = q - rs;
			q = rs;
		}
		var pr = station.market[c[i]].price / 10; ///
		if( remq > 0 ) rem += remq * pr;
	}
	
	var isac = false;
	var later = "";
	var muchlater = "";
	if( !this.$SellAllLimit ) {
		later = "Try again later";
		muchlater = " ... much later";
 		if( Math.floor( clock.hours/5 ) != clock.hours/5
			&& Math.floor( clock.days/7 ) != clock.days/7 ) {
 			muchlater = "";
			if( Math.floor( clock.minutes/3 ) != clock.minutes/3 )
				isac = true;
		}
	}
	
	if( max == 0 || rem > 0 && isac ) {
		var part = 2 + Math.min(2, rem / 2000); //put below half price but at least 1/4
		rem = Math.round( 10 * rem / part ) / 10;
		mission.runScreen({
			title: "Alternative Customer",
			message: "Hello, I am Isaac. Of course, that is not my real name but an acronym "
				+"from there IS An Alternative Customer somewhere."
				+"\n\nI see you have a problem selling all of your cargo as the market is full. "
				+"\nIf you promise that you will keep it in secret, I know a dealer who will buy "
				+"your excess cargo, but at a lower price... he will be taking a chance, you see."
				+"\n\nYou can get "+formatCredits(rem, false, true )
				+" if you confirm to sell all of your excess cargo.",
			background: this.$SellAllBG,
			screenID: "sellall",
			exitScreen: "GUI_SCREEN_MARKET",
			choices: {"_0" : "Yes","_1" : "No"}
		},function(choice) {
			if(choice == "_0") {
				for( var i = 0; i < c.length; i++ ) {
					var q = player.ship.manifest[c[i]];
					var rs = 0;
					if( max > 0 ) rs = max - station.market[c[i]].quantity;
					if( q > rs ) {
						var pr = station.market[c[i]].price/(10*part); //below half price
						player.ship.manifest[c[i]] = rs;
						this.SellAll_Notify(c[i], q, pr);
					}
				}
				if( rem > 100 && Math.random() < 0.1 ) {
					var msg = "You received nothing for your cargo, you get conned!";
					this.$SellAllSound3.play(); //boop
				} else {
					player.credits += rem;
					var msg = "You get "+formatCredits(rem, false, true );
					if( rem >= 200 && Math.random() < 0.2 ) {
						player.bounty += Math.ceil( rem / 500 );
						msg += " ... but watch your back, Commander!";
						this.$SellAllSound2.play(); //warning
					} else {
						msg += " from an alternative customer.";
						this.$SellAllSound.play(); //sell
					}
				}
				player.consoleMessage(msg, 10);
				log("SellAll", msg);
			}
		});
	} else {
		if( rem > 0 && !isac ) {
			mission.runScreen({
				title: "No Alternative Customer",
				message: "Isaac, the man who could help you to sell your excess cargo, "
					+"is not here at the moment. "+later+muchlater+"."
					+"\n\nMeantime, you can sell your cargo at the"
					+" normal market up to the standard capacity."
					+"\n\nAre you sure to sell?",
				background: this.$SellAllBG,
				screenID: "sellall",
				exitScreen: "GUI_SCREEN_MARKET",
				choices: {"_0" : "Yes", "_1" : "No"}
			},function(choice) {
				if(choice == "_0") {
					this.SellAll_Cargo();
				}
			});
		} else {
			mission.runScreen({
				title: "Normal Market",
				message: "You can sell all of your cargo at the normal market."
//					+"\nCome back here if you can't.",
					+"\n\nAre you sure to sell?",
				background: this.$SellAllBG,
				screenID: "sellall",
				exitScreen: "GUI_SCREEN_MARKET",
				choices: {"_0" : "Yes", "_1" : "No"}
			},function(choice) {
				if(choice == "_0") {
					this.SellAll_Cargo();
				}
			});
		}
	}
}

this.SellAll_GetCapacity = function(station) {
	var max = 127; //was fixed up to Oolite 1.80
	if (oolite.compareVersion("1.80") < 0 //in Oolite 1.81 or greater
		&& station && station.dataKey ) {
		var d = Ship.shipDataForKey(station.dataKey);
		if( d ) {
			if( d.market_capacity != null ) max = d.market_capacity;
			if( d.market_definition && d.market_definition.length > 0 ||
				d.market_script && d.market_script.length > 0 ) //needed by Kiotas
				max = 0;
			//too complex to check all custom markets so buy all goods instead
		}
	}
	return( max );
}

this.SellAll_Notify = function(c, q, pr) {
	var aa = worldScripts["AI Autotrade"];
	var mc = worldScripts["mo-commodity_markets"];
	var mo = worldScripts["market_observer"];
	if( aa ) aa.$notifyOtherScripts("sold", c, q, pr);
	else if( mc ) mc.$notifySell(c, q, pr);
	else if( mo ) mo.playerSoldCargo(c, q, pr);
}

this.SellAll_PressTimed = function() {
	var msg = "Press F8 to sell all of your cargo";
	var mo = worldScripts["market_observer"];
	if( mo ) mo.$printValues("                              "+msg+"\n\n"); //refresh market screen
	else player.consoleMessage(msg, 10);
	if( this.$SellAllPressTimer ) {
		this.$SellAllPressTimer.stop();
		delete this.$SellAllPressTimer;
	}
}