Config/script.js |
"use strict";
this.name = "System Redux";
this.author = "spara, redspear";
this.copyright = "spara, redspear 2014";
this.description = "Add a planet/moon combinations to each system. Derived from System Redux code by Kaks, CaptKev and Svengali";
this.licence = "CC-BY-SA 3.0";
this.version = "0.9";
//pools for textures
this.$planetPool = new Array();
this.$moonPool = new Array();
this.$giantPool = new Array();
this.planet_mult = 12;
this.moon_mult = 4.5;
this.libSettings = {Name:this.name, Display:"Config", Alias:this.name, Alive:"libSettings", Notify:"oxpcNotifyOnChange",
SInt:{
S0:{Name:"max_moons", Def:3, Min:0, Max:3, Desc:"Max number moons"},
S1:{Name:"max_planets", Def:4, Min:0, Max:4, Desc:"Max number planets"},
S2:{Name:"moon_mult", Def:2.5, Min:2.5, Max:8.0, Desc:"Moon dist mult", Float:true},
S3:{Name:"planet_mult", Def:5, Min:5.0, Max:12.0, Desc:"Planet dist mult", Float:true},
Info:"0 - Maximum number of moons, 1 - Maximum number of planets,\n2 - Moon distance multiplier, 3 - Planet distance multiplier\nChanges will take effect after save/reload or next jump."},
EInt:{
E0:{Name:"exSys", Def:0, Min:0, Max:7, Desc:["Lave","Diso","Tianve"]},
Info:"Exclude systems. If set, SystemRedux is bypassed in these systems.\nChanges may require save/reload."},
};
//public function to add planet textures to the pool
//call with array of texture names
this.addPlanetsToPool = function(planets) {
if (planets) {
for (var i = 0; i < planets.length; i++) {
if (this.$planetPool.indexOf(planets[i]) === -1)
this.$planetPool.push(planets[i]);
}
}
}
//public function to add moon textures to the pool
//call with array of texture names
this.addMoonsToPool = function(moons) {
if (moons) {
for (var i = 0; i < moons.length; i++) {
if (this.$moonPool.indexOf(moons[i]) === -1)
this.$moonPool.push(moons[i]);
}
}
}
//public function to add giant textures to the pool
//call with array of texture names
this.addGiantsToPool = function(giants) {
if (giants) {
for (var i = 0; i < giants.length; i++) {
if (this.$giantPool.indexOf(giants[i]) === -1)
this.$giantPool.push(giants[i]);
}
}
}
//public function to exclude specific systems
//call with an array of length 8 consisting of arrays of systems to exclude per galaxy
this.changeSystems = function(ar) {
if(ar){
//i galaxy, ar[i][j] system
for(var i=0;i<ar.length;i++){
for(var j=0;j<ar[i].length;j++){
if (this.excl[i].indexOf(ar[i][j]) === -1)
this.excl[i].push(ar[i][j]);
}
}
}
}
// public function to exclude a single system
// call with galaxy number and system ID
this.changeSystem = function(galID, sysID) {
if (galID >=0 && galID <=7) {
if (sysID >=0 && sysID <=255) {
if (this.excl[galID].indexOf(sysID) === -1) this.excl[galID].push(sysID);
}
}
}
//oxp config
this.oxpcSettings = {
Info: {Name:"System Redux",EarlyCall:true,EarlySet:true,Notify:true,
InfoE:"Exclude systems. If set SystemRedux is bypassed in these systems.\nChanges may require restart / reload."
},
SInt0: {Name:"max_moons",Def:0x3,Max:0x3,Desc:"Max number of moons"},
SInt1: {Name:"max_planets",Def:0x4,Max:0x4,Desc:"Max number of planets"},
EInt0: {Name:"exSys",Def:0x0,Max:0x7,Desc:["Lave","Diso","Tianve"]}
};
this.oxpcNotifyOnChange = function(n) {
var idx = this.excl[0].indexOf(7);
if((this.exSys&1)) {
if (idx == -1) this.excl[0].push(7); //Lave
} else {
if (idx >= 0) this.excl[0].splice(idx, 1);
}
idx = this.excl[0].indexOf(147);
if((this.exSys&2)) {
if (idx == -1) this.excl[0].push(147); //Diso
} else {
if (idx >= 0) this.excl[0].splice(idx, 1);
}
idx = this.excl[0].indexOf(246);
if((this.exSys&4)) {
if (idx == -1) this.excl[0].push(246); //Tianve
} else {
if (idx >= 0) this.excl[0].splice(idx, 1);
}
return;
}
this.startUp = function() {
//4 moons are currently defined in the planetdata.
this.max_moons = 1;//max number of moons around a planet. There's no limit here.
this.max_planets = 2;//maximum number of extra planets per system. extra planets might have moon. There's no limit here.
this.extraPlanetMoonsProbability = 0.1;//the probablitity for an extra planet to have moons.
this.exSys = 0;//for oxp config
this.excl = [[],[],[],[],[],[],[],[]];//excluded systems
this.systemDone = false;//flag so that system gets populated only once
this.runOnce = true;//controls the sorting of the pools
if (missionVariables.SystemRedux_MaxMoons) this.max_moons = parseInt(missionVariables.SystemRedux_MaxMoons);
if (missionVariables.SystemRedux_MaxPlanets) this.max_planets = parseInt(missionVariables.SystemRedux_MaxPlanets);
if (missionVariables.SystemRedux_PlanetDistMult) this.planet_mult = parseFloat(missionVariables.SystemRedux_PlanetDistMult);
if (missionVariables.SystemRedux_MoonDistMult) this.moon_mult = parseFloat(missionVariables.SystemRedux_MoonDistMult);
if (missionVariables.SystemRedux_Exclude) this.exSys = JSON.parse(missionVariables.SystemRedux_Exclude);
}
this.startUpComplete = function() {
// register our settings, if Lib_Config is present
if (worldScripts.Lib_Config) worldScripts.Lib_Config._registerSet(this.libSettings);
}
this.playerWillSaveGame = function() {
missionVariables.SystemRedux_MaxMoons = this.max_moons;
missionVariables.SystemRedux_MaxPlanets = this.max_planets;
missionVariables.SystemRedux_PlanetDistMult = this.planet_mult;
missionVariables.SystemRedux_MoonDistMult = this.moon_mult;
missionVariables.SystemRedux_Exclude = JSON.stringify(this.exSys);
}
this.systemWillPopulate = function (){
//sort the pools on first launch so that the textures stay consistently regardless of the load order of the texture packs
if (this.runOnce) {
this.$planetPool.sort();
this.$moonPool.sort();
this.runOnce = false;
}
if(this.excl[galaxyNumber].indexOf(system.ID)===-1) {
//init station array in sfap oxp
if (worldScripts["stations_for_extra_planets"])
worldScripts["stations_for_extra_planets"].initStationArray();
this.$addPlanets();
}
}
//the actual planet populator
this.$addPlanets = function() {
//temporary arrays to be used with splice so that no two planet/moons/giant get the same texture in one system
var tempPlanets = new Array();
tempPlanets = tempPlanets.concat(this.$planetPool);
var tempMoons = new Array();
tempMoons = tempMoons.concat(this.$moonPool);
var tempGiants = new Array();
tempGiants = tempGiants.concat(this.$giantPool);
var usedTextures = new Array();
//inner functions need this
var max_moon = this.max_moons;
//function to manage textures so that if the same texture is used as moon and planet, it won't get shown twice in the same system
function getTexture(pool, seed) {
while (true) {
if (pool.length !== 0) {
var texNum = Math.floor(system.scrambledPseudoRandomNumber(seed) * pool.length);
var texture = pool.splice(texNum, 1)[0];
if (usedTextures.indexOf(texture) === -1) {
usedTextures.push(texture);
return texture;
}
}
else return null;
}
}
//function to add moons around given planet
function addMoons(planet_position, planet_radius, seed) {
//number of moon sizes defined in planetinfo.plist
var moonSizes = 4;
//number of moons to be added. extremes have probability weight of 0.5, others 1.
var numberOfMoons = Math.round(system.scrambledPseudoRandomNumber(seed) * max_moons);
//orbits. lowest is 2.5 * planet radius. station is usually at 2 * planet radius.
var moonOrbits = new Array();
for (var i = 0; i < max_moons; i++) moonOrbits.push(i);
var baseMoonOrbit = planet_radius * worldScripts["System Redux"].moon_mult;
var moonOrbitDifference = 30000;
//for cinematic reasons moons are positioned so that when you view the main planet from wp, you should be able to see all the moons around it.
//wp-planet line is kept empty.
for (var i = 0; i < numberOfMoons; i++) {
//texture
var moonTexture = getTexture(tempMoons, system.scrambledPseudoRandomNumber(2 * (seed + i)));
if (moonTexture === null) return;//if we're out of textures, abort.
//body
var moonBody = "ap-moon" + Math.floor(system.scrambledPseudoRandomNumber(3 * (seed + i)) * moonSizes);
//position
var moonOrbit = moonOrbits.splice(Math.floor(system.scrambledPseudoRandomNumber(11 * (seed + i)) * moonOrbits.length), 1)[0];
var polar = Math.acos(1.4 * system.scrambledPseudoRandomNumber(5 * (seed + i)) - 0.7);
var azimuth = 2.0 * Math.PI * system.scrambledPseudoRandomNumber(7 * (seed + i));
var directionV = Vector3D(Math.sin(polar) * Math.cos(azimuth), Math.sin(polar) * Math.sin(azimuth), Math.cos(polar));
var distance = baseMoonOrbit + moonOrbitDifference * moonOrbit;
var moonPosition = planet_position.toCoordinateSystem("pwm").add(directionV.multiply(distance)).fromCoordinateSystem("pwm");
setPopulatorMoon(moonTexture, moonBody, moonPosition);
}
}
function setPopulatorPlanet(texture, body, coords, giant, radius) {
system.setPopulator("ap_planet"+texture, {
callback: function(pos) {
var addedPlanet = system.addPlanet(body);
addedPlanet.texture = texture;
if (giant) {
//for planetfall
addedPlanet.solarGasGiant = true;
//for gas giant skimmer
addedPlanet.isGasGiant = true;
}
addedPlanet.position = pos;
}.bind(this),
location: "COORDINATES",
coordinates: coords,
priority: 100
});
//add station to planets with atmosphere
if (worldScripts["stations_for_extra_planets"] && !giant)
worldScripts["stations_for_extra_planets"].setStationPopulator(coords, radius);
}
function setPopulatorMoon(texture, body, coords) {
system.setPopulator("ap_moon"+texture, {
callback: function(pos) {
var addedMoon = system.addMoon(body);
addedMoon.texture = texture;
addedMoon.position = pos;
}.bind(this),
location: "COORDINATES",
coordinates: coords,
priority: 101
});
}
//all extra planets are positioned on incrementing distances calculated from the main planet. baseOrbit is the distance of the closest possible planet and orbitDifference is the increment from there on. These are multiples of unit calculated from wp-planet distance, so they differ from system to system. unit range is ~ 300 km - 400 km. For reference wp-planet range is ~ 300 km - 900 km.
var orbits = new Array();
for (var i = 0; i < this.max_planets; i++) orbits.push(i);
var baseUnit = 1.0 / 6.0 * system.mainPlanet.position.magnitude() + 250000;
var baseOrbit = this.planet_mult * baseUnit;//I would not go under 5. With 4, it's possible that an added planet is as close to the wp buoy as the main planet.
var orbitDifference = 2.5 * baseUnit;
//the number of extra planets in system. using Math.round gives smaller probabilities to the extremes, 0 and this.max_planets. With max planets 4, you'll be seeing more 1-3 extra planet systems than 0 or 4 extra planet systems. Probabitity weights are 0.5, 1, 1, 1, 0.5.
var planetsInSystem = Math.round(system.pseudoRandomNumber * this.max_planets);
for (var i = 0; i < planetsInSystem; i++) {
//orbit.
var orbit = orbits.splice(Math.floor(system.scrambledPseudoRandomNumber(galaxyNumber + 7 * (i + 1)) * orbits.length),1)[0];
//planet size. there are 9+1 different sizes defined in planetinfo.plist. 10th is reserved for gas giants that can only appear on outer orbits.
var planetSizes = 9;
if (orbit > 1 && tempGiants.length > 0) planetSizes = 10;
var planetInd = Math.floor(system.scrambledPseudoRandomNumber(galaxyNumber + 2 * (i + 1)) * planetSizes);
//texture
if (planetInd === 9)
var planetTexture = getTexture(tempGiants, system.scrambledPseudoRandomNumber(galaxyNumber + 11 * (i + 1)));
else
var planetTexture = getTexture(tempPlanets, system.scrambledPseudoRandomNumber(galaxyNumber + 11 * (i + 1)));
if (planetTexture === null) continue; //if we're out of textures, skip to the next iteration.
//body
var planetBody = "ap-planet" + planetInd;
if (planetInd === 9) var giant = true;
else var giant = false;
//position. planet is placed on a zone of a sphere around the main planet opposite to the sun.
var polar = Math.acos(1.4 * system.scrambledPseudoRandomNumber(galaxyNumber + 5 * (i + 1)) - 1);
var azimuth = 2.0 * Math.PI * system.scrambledPseudoRandomNumber(galaxyNumber + 3 * (i + 1));
var directionV = Vector3D(Math.sin(polar) * Math.cos(azimuth), Math.sin(polar) * Math.sin(azimuth), Math.cos(polar));
var distance = baseOrbit + orbitDifference * orbit;
var planetPosition = directionV.multiply(distance).fromCoordinateSystem("psm");
var radiuses = [5000, 5250, 5500, 5750, 6000, 6250, 6500, 6750, 7000, 20000];
setPopulatorPlanet(planetTexture, planetBody, planetPosition, giant, radiuses[planetInd]*10);
//moons for extra planets
if (system.scrambledPseudoRandomNumber(galaxyNumber + 17 * (i + 1)) < this.extraPlanetMoonsProbability) {
//positioning depends on planet radius. Moon populator is set before the planet is added. Hence radiuses are given here.
addMoons(planetPosition, radiuses[planetInd]*10, galaxyNumber + 13);
}
}
addMoons(system.mainPlanet.position, system.mainPlanet.radius, galaxyNumber + 19);
}
|