Scripts/riskybusiness.js |
"use strict";
this.author = "phkb";
this.copyright = "2021 phkb";
this.licence = "CC-BY-SA-NC 4.0";
this.name = "RiskyBusiness_Main";
this.description = "Adjusts prices according to system danger level - so dangerous systems have more reward for traders";
this._trueValues = ["yes", "1", 1, "true", true];
this._riskBasedEconomy = true;
this._riskyBusiness = true;
this._logging = false;
this.$tvols = [[],[],[],[],[],[],[],[]]; // cache variable for risk-based-economy
this._rbConfig = {Name:this.name, Alias:"Risky Business", Display:"Config", Alive:"_rbConfig",
Bool:{
B0:{Name:"_riskBasedEconomy", Def:true, Desc:"Include 'Risk Based Economy'"},
B1:{Name:"_riskyBusiness", Def:true, Desc:"Include 'Risky Business'"},
B2:{Name:"_logging", Def:false, Desc:"Output info to log"},
Info:"0 - Includes logic from 'Risk Based Economy'.\n1 - Includes logic from 'Risky Business'.\n2 - Output extra info to log file."}
};
//-------------------------------------------------------------------------------------------------------------
this.startUp = function() {
var msi = worldScripts.MarketScriptInterface_Main;
msi.$addMarketInterface("system_local", "$updateLocalCommodityDefinition", this.name);
if (missionVariables.RiskyBusiness_RBE) this._riskBasedEconomy = (this._trueValues.indexOf(missionVariables.RiskyBusiness_RBE) >= 0 ? true : false);
if (missionVariables.RiskyBusiness_Risky) this._riskyBusiness = (this._trueValues.indexOf(missionVariables.RiskyBusiness_Risky) >= 0 ? true : false);
if (missionVariables.RiskyBusiness_Logging) this._logging = (this._trueValues.indexOf(missionVariables.RiskyBusiness_logging) >= 0 ? true : false);
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
// register our settings, if Lib_Config is present
if (worldScripts.Lib_Config) {
worldScripts.Lib_Config._registerSet(this._rbConfig);
}
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function() {
missionVariables.RiskyBusiness_RBE = this._riskBasedEconomy;
missionVariables.RiskyBusiness_Risky = this._riskyBusiness;
missionVariables.RiskyBusiness_Logging = this._logging;
}
/*
Other factors to consider:
system economy - increase or decrease bias
number of local systems - more neighbours means more traffic, increase or decrease traffic
*/
//-------------------------------------------------------------------------------------------------------------
this.$updateLocalCommodityDefinition = function (good, station, systemID) {
if (station) return good; // shouldn't be necessary
if (!worldScripts.RiskyBusiness_Control || worldScripts.RiskyBusiness_Control._riskBasedEconomy) good = this.rbe_updateLocalCommodityDefinition(good, station, systemID);
if (!worldScripts.RiskyBusiness_Control || worldScripts.RiskyBusiness_Control._riskyBusiness) good = this.rb_updateLocalCommodityDefinition(good, station, systemID);
return good;
}
//-------------------------------------------------------------------------------------------------------------
this.rb_updateLocalCommodityDefinition = function (good, station, systemID) {
var info = System.infoForSystem(galaxyNumber, systemID);
var sys = info.government; // 0 = anarchy, 7 = corporate
// if we're in a system we're not adjusting, just return the good with no change
if (sys >= 3) return good;
// not all goods will be impacted
// we're using sort_order for a seed, so that for any system, the same goods will be adjusted,
// because the sort order shouldn't change and is unique for each good
// this adds some predictability to the changes, but also means there is benefit to searching out the best locations
if (this.$customPseudoRandomNumber(galaxyNumber, systemID, good.sort_order) > 0.25) return good; // only 25% chance a good will be changed
var old_price = good.price;
// the random factor will be the same on any given day
var bias = ((7 - sys) + 3) / 7 + ((this.$customPseudoRandomNumber(galaxyNumber, systemID, clock.days) * 0.2) - 0.1);
var diff = good.price - good.price_average;
// apply the bias to the difference
// if the price is lower than the average, make it a super-special
if (diff < 0) bias = 1 - (bias - 1);
// check for an edge case where the applied change would make the price less than 0.
// this could happen if the average price is much greater than or less than the normal price
if (Math.floor(good.price + (diff * bias)) < 0) return good;
// ok, we should be good to go now
good.price = Math.floor(good.price + (diff * bias));
if (worldScripts.RiskyBusiness_Control && worldScripts.RiskyBusiness_Control._logging) log(this.name, "Adjusted " + good.key + " from " + old_price + " to " + good.price + " (avr_price=" + good.price_average + ",bias=" + bias + ",diff=" + diff + ",sys=" + systemID + ")");
return good;
}
//-------------------------------------------------------------------------------------------------------------
this.$customPseudoRandomNumber = function (galid, sysid, salt) {
// because we can't use scrambledPseudoRandomNumber for systems we aren't in
var n = (sysid + (galid * 256)) * (salt * 512) + salt;
n = (214013 * n + 2531011) & 0xFFFFFFFF;
n = (214013 * n + 2531011) & 0xFFFFFFFF;
n = (214013 * n + 2531011) & 0xFFFFFFFF;
return n / 4294967296.0 + 0.5;
}
//-------------------------------------------------------------------------------------------------------------
/*
Risk-Based Economy
Adjusts prices according to trade volume - so safer systems have more 'centred' prices, and hub systems have more 'centred' prices.
Author: cim
Copyright 2011-2014 cim.
Licence: CC-BY-SA 3.0
Version: 2.0
*/
this.rbe_updateLocalCommodityDefinition = function (good, station, system) {
var info = System.infoForSystem(galaxyNumber, system);
// var tvol = worldScripts["oolite-populator"].$repopulatorFrequencyIncoming.traderFreighters; // generally in 0.025 .. 0.1 range with 0.05 being reasonably typical
// tvol hasn't actually been generated at this point, though, so
// must calculate it separately here
if (!this.$tvols[galaxyNumber][system.ID]) {
var freighters = 0;
var locals = info.systemsInRange();
for (var i = 0; i < locals.length; i++) {
// standard freighter traffic is mirrored
var local = locals[i];
// traffic is higher between systems on opposite side of economy
var ecomatch = -(info.economy - 3.5) * (local.economy - 3.5);
var trdanger = 0;
var rate = 0;
// if either local or remote end is more dangerous than
// Communist, reduce trader frequency
if (local.government < 4) {
trdanger = (4 - local.government) * 2.5;
}
if (info.government < 4) {
trdanger += (4 - info.government) * 2.5;
}
// good economic match: one every 30 minutes if safe
if (ecomatch > 0) {
rate = 60 / (30 + trdanger);
}
// bad economic match: one every 2 hours if safe
else {
rate = 60 / (120 + (trdanger * 2));
}
freighters += rate;
}
this.$tvols[galaxyNumber][system.ID] = freighters / 180;
}
var tvol = this.$tvols[galaxyNumber][system.ID];
// this has already been counted a bit above, but count it again
// because that doesn't allow for how many actually get through
var sys = info.government; // 0 = anarchy, 7 = corporate
var bias = ((tvol + sys * 0.01) - 0.07) * 10;
// approximate range -0.5 ..0.8
bias = bias * (0.75 + Math.random() / 2);
if (bias > 0.9) {
bias = 0.9;
}
// adjusted range -0.625 .. 1.0
// positive means "centre this more"
var oldprice = good.price;
good.price = Math.floor(good.price + ((good.price_average - good.price) * bias));
if (worldScripts.RiskyBusiness_Control && worldScripts.RiskyBusiness_Control._logging) log(this.name, "Adjusted " + good.key + " from " + oldprice + " to " + good.price + " (bias=" + bias + " => " + tvol + "," + sys + ")");
return good;
} |