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