Scripts/market_observer.js |
"use strict";
this.name = "market_observer3";
this.author = "spara";
this.description = "Show extra market information";
this.startUp = function() {
this.$basisLimit = 100 //current avg is weighted with this value
//init price gatherer
if (!missionVariables.marketObserver3) {
this.$priceData = new Object();
}
else {
this.$priceData = JSON.parse(missionVariables.marketObserver3);
}
//init purchase log
if (!missionVariables.marketObserverBuyLog3) {
this.$buyLog = new Object();
}
else {
this.$buyLog = JSON.parse(missionVariables.marketObserverBuyLog3);
}
//init contracted goods
if (!missionVariables.marketObserverContracted) {
this.$contracted = new Object();
}
else {
this.$contracted = JSON.parse(missionVariables.marketObserverContracted);
}
}
this.startUpComplete = function() {
//for compatibility with commodity markets oxp. it changes system market in market screen
this.$sMarket = system.mainStation.market;
//on start up, check for new commodities.
var sMarket = this.$sMarket;
for (var i in sMarket) {
if (!this.$priceData[i]) {
this.$updatePriceData();
break;
}
}
}
this.playerWillSaveGame = function () {
missionVariables.marketObserver3 = JSON.stringify(this.$priceData);
missionVariables.marketObserverBuyLog3 = JSON.stringify(this.$buyLog);
missionVariables.marketObserverContracted = JSON.stringify(this.$contracted);
}
//mark commodities as contracted to be noted when player buys or sells. contracted goods do not affect trader's rating.
this.playerEnteredContract = function(type, contract) {
if (type === "cargo") {
var commodity = contract.co_type;
if (this.$contracted[commodity]) {
this.$contracted[commodity] += contract.co_amount;
}
else this.$contracted[commodity] = contract.co_amount
}
}
//release commodities for being marked as contracted.
this.playerCompletedContract = function(type, result, fee, contract) {
if (type === "cargo") {
var commodity = contract.co_type;
if (this.$contracted[commodity]) {
this.$contracted[commodity] -= contract.co_amount;
if (this.$contracted[commodity] <= 0) {
delete this.$contracted[commodity];
}
}
}
}
//cancel contracts when entering new galaxy as core does
this.playerEnteredNewGalaxy = function(galaxyNumber) {
this.$contracted = new Object();
}
//update system prices when exiting WS
this.shipExitedWitchspace = function() {
if (system.mainStation) {
this.$updatePriceData();
this.$sMarket = system.mainStation.market;
}
}
//update average
this.$updatePriceData = function() {
var sMarket = this.$sMarket;
for (var i in sMarket) {
//update the average of a known commodity using a weighting from this.$basisLimit
if (this.$priceData[i]) {
var avgBasis = this.$basisLimit;
this.$priceData[i].average = (avgBasis * this.$priceData[i].average + sMarket[i].price) / (avgBasis + 1);
}
//init a new commodity using average from commodity def
else {
//there's a rare possibility that the commodity has no price_average
if (sMarket[i].price_average) {
this.$priceData[i] = {
average: sMarket[i].price_average
}
}
else {
this.$priceData[i] = {
average: sMarket[i].price
}
}
}
}
}
//update purchase log
this.playerBoughtCargo = function(commodity, units, price) {
//there's a contract on commodity
if (this.$contracted[commodity]) {
var prevQuantity = player.ship.manifest[commodity] - units;
var replaced = 0;
//in case we replacing contracted goods, don't note replaced units on log/rating
while (prevQuantity < this.$contracted[commodity] && units > 0) {
prevQuantity += 1;
units--;
replaced++;
}
if (replaced > 0) {
player.consoleMessage(replaced + " units of contracted goods replaced.");
}
}
if (units > 0) {
if (this.$buyLog[commodity]) {
//handle buying the same commodity multiple times
if (this.$buyLog[commodity][0][1] === price) {
this.$buyLog[commodity][0][0] += units;
this.$updateManifestExtras();
return;
}
}
else {
this.$buyLog[commodity] = new Array();
}
this.$buyLog[commodity].unshift([units, price]);
this.$updateManifestExtras();
}
}
//update purchace log
this.playerSoldCargo = function(commodity, units, price) {
if (!this.$buyLog[commodity]) return;
var i, currentElement;
var tab = "";
var unitCount = units;
var profit = 0;
while(unitCount > 0 && this.$buyLog[commodity].length > 0) { //purge buys from log
currentElement = this.$buyLog[commodity].shift();
//There is more than enough purchases in one log entry
if (currentElement[0] > unitCount) {
profit += unitCount * (price - currentElement[1]);
currentElement[0] -= unitCount;
this.$buyLog[commodity].unshift(currentElement);
unitCount = 0;
}
//There is enough or less purchases in log entry
else {
profit += currentElement[0] * (price - currentElement[1]);
unitCount -= currentElement[0];
}
}
if (this.$buyLog[commodity].length === 0)
delete this.$buyLog[commodity];
//show profit if profit != 0
if (profit !== 0) {
player.consoleMessage("Profit by trade: "+formatCredits(profit/10, true, true ));
worldScripts["mo-traders_rating3"].$reportProfit(profit);
}
this.$updateManifestExtras();
}
this.shipDockedWithStation = function(station) {
//this is here for compatibility with commodity markets oxp. it changes system market when docked at main station
if (station.isMainStation) {
this.$sMarket = system.mainStation.market;
}
//write off lost cargo from the profit when docking
var profitLoss = 0;
for (var i in this.$buyLog) {
if (!manifest[i]) var unitsInCargo = 0;
else var unitsInCargo = manifest[i];
var done = false;
while (!done) {
var unitsInLog = 0;
//calculate total number of units in log
for (var j = 0; j < this.$buyLog[i].length; j++) {
unitsInLog += this.$buyLog[i][j][0];
}
var difference = unitsInLog - unitsInCargo;
//check if cargo is missing
if (difference > 0) {
//the last log entry has more than enough units to be removed, no need to remove entries
if (this.$buyLog[i][this.$buyLog[i].length-1][0] > difference) {
profitLoss += this.$buyLog[i][this.$buyLog[i].length-1][1] * difference;
this.$buyLog[i][this.$buyLog[i].length-1][0] -= difference;
done = true;
}
//the last log entry has enough or less than enough units to be removed, need to remove last entry
else {
profitLoss += this.$buyLog[i][this.$buyLog[i].length-1][1] * difference;
this.$buyLog[i].pop();
}
}
else {
done = true;
if (this.$buyLog[i].length === 0) delete this.$buyLog[i];
}
}
}
if (profitLoss > 0) {
worldScripts["mo-traders_rating3"].$reportProfit(-1 * profitLoss);
player.consoleMessage(formatCredits(profitLoss/10, true, true )+" worth of cargo is lost.");
}
this.$updateManifestExtras();
}
this.shipLaunchedFromStation = function(station) {
for (var i in this.$buyLog) {//sort purchase log descending
this.$buyLog[i].sort(function(a, b){return b[1] - a[1]});
}
this.$updateManifestExtras();
}
this.guiScreenWillChange = function(to, from) {
if (to === "GUI_SCREEN_MARKET") this.$updateManifestExtras();
}
//tabbing function, prefixes pads to the string
//order true postfixes with pads
this._tabulate = function(string, width, order) {
var hairSpace = String.fromCharCode(31);
var hairSpaceLength = defaultFont.measureString(hairSpace);
var currentLength = global.defaultFont.measureString(string);
var padsNeeded = Math.floor((width - currentLength) / hairSpaceLength);
if (padsNeeded >= 1)
var pads = new Array(padsNeeded).join(hairSpace);
else var pads = "";
if (!order) return (pads + string);
else return (string + pads);
}
this._percentDiff = function(avg, local, capacity) {
if (capacity !== 0) {
var percent = (local - avg) / avg * 100;
if (percent < -0.05) {
var percentText = percent.toFixed(1) + " %%";
}
else if (percent > 0.05) {
var percentText = "+" + percent.toFixed(1) + " %%";
}
else var percentText = "0.0 %%";
}
//no point in calculating difference for 0 prices.
else var percentText = "— %%";
return percentText;
}
this._absDiff = function(avg, local, capacity) {
if (capacity !== 0) {
var abs = (local - avg)/10;
if (abs < -0.05) {
var absText = abs.toFixed(1);
}
else if (abs > 0.05) {
var absText = "+" + abs.toFixed(1);
}
else var absText = "0.0";
}
//no point in calculating difference for 0 prices.
else var absText = "—";
return absText;
}
this.$updateManifestExtras = function() {
//check what market is being shown
if (player.ship.docked) {
var sMarket = player.ship.dockedStation.market;
}
else {
if (player.ship.target && player.ship.target.isStation) {
var bcMarket = Ship.shipDataForKey(player.ship.target.dataKey)["market_broadcast"];
if (!bcMarket) bcMarket = true;
else {
var trues = ["1", "true", "yes"];
bcMarket = bcMarket.toLowerCase();
if (trues.indexOf(bcMarket) !== -1) bcMarket = true;
else bcMarket = false;
}
if (bcMarket) var sMarket = player.ship.target.market;
else var sMarket = this.$sMarket;
}
else var sMarket = this.$sMarket;
}
var cm = worldScripts["commodity_markets"];
for (var i in sMarket) {
//first we'll need to clean our possible earlier additions from comment
//there might be other content so we'll do what we can to preserve that.
//we're assuming (foolhardy?) that we're the last entry.
var cmt = manifest.comment(i);
if (cmt.indexOf("Purchase breakdown") !== -1) {
var sliceIndex = cmt.indexOf("Purchase breakdown") - 2;
cmt = cmt.slice(0, sliceIndex);
manifest.setComment(i, cmt);
}
//average column
var line = this._tabulate(formatCredits(this.$priceData[i].average/10, true, false), 2.4);
//differences colums
if (!system.isInterstellarSpace) {
line += this._tabulate(this._absDiff(this.$priceData[i].average, sMarket[i].price, sMarket[i].capacity), 3);
line += this._tabulate(this._percentDiff(this.$priceData[i].average, sMarket[i].price, sMarket[i].capacity), 4.5);
}
var buyColWidth = 17.5;
//add possible commodity markets column
if (player.ship.docked && cm) {
line += this._tabulate(formatCredits(cm.$commodities[i][1]/10, true, false), 5.3);
buyColWidth -= 5.3;
}
//add puchase log column
if (this.$buyLog[i]) {
line += this._tabulate(this.$buyLog[i][0][0] + " × ", buyColWidth);
line += formatCredits(this.$buyLog[i][0][1]/10, true, false);
//more that one entry in log
if (this.$buyLog[i].length > 1) line += " >";
//commodity details (f8-f8)
// 6 entries per line
cmt += "\n\nPurchase breakdown of held cargo: ";
var j = 0;
while (j < this.$buyLog[i].length) {
cmt += "\n";
for (var k = j; k < j + 6; k++) {
if (k < this.$buyLog[i].length) {
cmt += this._tabulate(this.$buyLog[i][k][0] + " × ", 2.6);
cmt += this._tabulate(formatCredits(this.$buyLog[i][k][1]/10, true, false), 2.7, true);
}
else break;
}
j += 6;
}
manifest.setComment(i, cmt);
}
manifest.setShortComment(i, line);
}
}
|
Scripts/mo_traders_rating.js |
"use strict";
this.name = "mo-traders_rating3";
this.author = "spara";
this.description = "Gives the player a Trader's Rating based on profit made.";
//Public function for reporting profit
this.$reportProfit = function(profit) {
this.$profit += profit;
this.$setInstruction();
}
this.startUp = function() {
if (!missionVariables.marketObserverProfit) this.$profit = 0;
else this.$profit = missionVariables.marketObserverProfit;
this.$setInstruction();
}
this.playerWillSaveGame = function () {
missionVariables.marketObserverProfit = this.$profit;
}
this.$traderRank = function() { //return trader rank string
var traderRatings =[0, 1500, 5000, 20000, 50000, 100000, 250000, 500000, 1000000];
var i;
var traderRating = -1;
for (i = 0; i < 9; i++) {
if (this.$profit/10 >= traderRatings[i])
var traderRating = i;
}
if (traderRating != -1)
return expandDescription("[mo_trade_rating_" + traderRating+"]");
else
return expandDescription("[mo_trade_rating_minus]");
}
//Trader rank for market hud
this.$setInstruction = function() { //set trader rank text to manifest
var traderRank = "Trader's Rating: " + this.$traderRank() + " (" + formatCredits(this.$profit/10, true, true ) + ")";
player.ship.setCustomHUDDial("marketObserverProfit", traderRank);
mission.setInstructions(traderRank+".", this.name);
}
|