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