Updated the code to the new version found on loewald.com/galaxygen
(after some heavy refactoring)
This commit is contained in:
parent
6b9d48c604
commit
3a8803318b
139
Astrophysics.js
Normal file
139
Astrophysics.js
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
class Astrophysics {
|
||||||
|
static gravity(radius, density) {
|
||||||
|
return density / 5.56 * radius / 6557;
|
||||||
|
}
|
||||||
|
|
||||||
|
static blackbody(insolation, albedo = 0) {
|
||||||
|
return Math.pow((1367 * insolation * (1 - albedo)) / (4 * 0.0000000567), 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HI(insolation, radius, density, hydrographics, atmosphere) {
|
||||||
|
const g = Astrophysics.gravity(radius, density).toFixed(2);
|
||||||
|
const { albedo } = atmosphere ? Astrophysics.atmosphereData[atmosphere] : 0;
|
||||||
|
const tempK = Astrophysics.blackbody(insolation, albedo + hydrographics * 0.002).toFixed(1);
|
||||||
|
const tempC = (tempK- 275.15).toFixed(1);
|
||||||
|
|
||||||
|
let temperature;
|
||||||
|
|
||||||
|
if (tempC < -150) {
|
||||||
|
temperature = 'frigid';
|
||||||
|
}
|
||||||
|
else if (tempC < -70) {
|
||||||
|
temperature = 'very cold';
|
||||||
|
}
|
||||||
|
else if (tempC < -10) {
|
||||||
|
temperature = 'cold';
|
||||||
|
}
|
||||||
|
else if (tempC < 30) {
|
||||||
|
temperature = 'temperate';
|
||||||
|
}
|
||||||
|
else if (tempC < 60) {
|
||||||
|
temperature = 'hot';
|
||||||
|
}
|
||||||
|
else if (tempC < 120) {
|
||||||
|
temperature = 'very hot';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
temperature = 'inferno';
|
||||||
|
}
|
||||||
|
|
||||||
|
let data;
|
||||||
|
|
||||||
|
if (atmosphere === 'Breathable' && hydrographics > 0 && g < 1.25 && ['cold', 'hot', 'temperate'].indexOf(temperature) > -1) {
|
||||||
|
data = { HI: 1, description: 'earthlike' };
|
||||||
|
}
|
||||||
|
else if (['Breathable', 'Filterable'].indexOf(atmosphere) > -1 && g < 2 && ['inferno', 'frigid'].indexOf(temperature) === -1) {
|
||||||
|
data = { HI: 2, description: 'survivable' };
|
||||||
|
}
|
||||||
|
else if (atmosphere === 'Corrosive' || g > 3 || ['inferno', 'frigid'].indexOf(temperature) > -1) {
|
||||||
|
data = tempC > 800 ? { HI: 5, description: 'inimical' } : { HI: 1, description: 'robot accessible' };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data = { HI: 3, description: 'EVA possible' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.assign(data, { g, albedo, tempC, temperature });
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Astrophysics.starTypeData = {
|
||||||
|
'O': {
|
||||||
|
luminosity: 50000, color: 0xFFC0FF, planets: [0, 3]
|
||||||
|
},
|
||||||
|
'B': {
|
||||||
|
luminosity: 15000, color: 0xC0A0FF, planets: [1, 5]
|
||||||
|
},
|
||||||
|
'A': {
|
||||||
|
luminosity: 25, color: 0x80C0FF, planets: [1, 7]
|
||||||
|
},
|
||||||
|
'F': {
|
||||||
|
luminosity: 2.5, color: 0xA0FF80, planets: [1, 11]
|
||||||
|
},
|
||||||
|
'G': {
|
||||||
|
luminosity: 1, color: 0xFFFF40, planets: [1, 19]
|
||||||
|
},
|
||||||
|
'K': {
|
||||||
|
luminosity: 0.25, color: 0xFFC040, planets: [1, 9]
|
||||||
|
},
|
||||||
|
'M': {
|
||||||
|
luminosity: 0.05, color: 0xFF4000, planets: [1, 5]
|
||||||
|
},
|
||||||
|
'black hole': {
|
||||||
|
luminosity: 100000, color: 0x800040, planets: [0, 0]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Astrophysics.atmosphereData = {
|
||||||
|
Breathable: {
|
||||||
|
albedo: 0.2, density: 1
|
||||||
|
},
|
||||||
|
Filterable: {
|
||||||
|
albedo: 0.3, density: 1
|
||||||
|
},
|
||||||
|
Inert: {
|
||||||
|
albedo: 0.1, density: 0.5
|
||||||
|
},
|
||||||
|
Corrosive: {
|
||||||
|
albedo: 0.5, density: 2
|
||||||
|
},
|
||||||
|
Toxic: {
|
||||||
|
albedo: 0.4, density: 1.5
|
||||||
|
},
|
||||||
|
Trace: {
|
||||||
|
albedo: 0.05, density: 0.1
|
||||||
|
},
|
||||||
|
Crushing: {
|
||||||
|
albedo: 0.8, density: 100
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Astrophysics.planetTypeData = [
|
||||||
|
{
|
||||||
|
classification:'rocky',
|
||||||
|
radius: [1000,15000],
|
||||||
|
density: [2,8],
|
||||||
|
hydrographics: function(pnrg, insolation, radius, density) {
|
||||||
|
let g = Astrophysics.gravity(radius, density),
|
||||||
|
tempK = Astrophysics.blackbody(insolation, 0);
|
||||||
|
return Math.clamp(pnrg.realRange(-50, 150 - Math.abs(tempK - 270)) * g - Math.abs(density - 5.5) * 10, 0, 100).toFixed(0);
|
||||||
|
},
|
||||||
|
atmosphere: function(pnrg, insolation, radius, density, hydrographics) {
|
||||||
|
let g = Astrophysics.gravity(radius, density);
|
||||||
|
if (hydrographics > 0 && insolation > 0.25 && insolation < 2) {
|
||||||
|
return pnrg.pick(['Breathable', 'Filterable', 'Inert', 'Toxic', 'Corrosive', 'Trace'], [1, 2, 2, 1, 1, 1]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return pnrg.pick(['Breathable', 'Filterable', 'Inert', 'Toxic', 'Corrosive', 'Trace'], [1, 2, 3, 4, 5, 5]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
HI: Astrophysics.HI
|
||||||
|
},
|
||||||
|
{
|
||||||
|
classification: 'gas giant', radius: [15000, 120000], density: [0.6, 2.0], hydrographics: 0, atmosphere: 'Crushing', HI: Astrophysics.HI
|
||||||
|
},
|
||||||
|
{
|
||||||
|
classification: 'brown dwarf', radius: [120000, 250000], density: [0.6, 2.0], hydrographics: 0, atmosphere: 'Crushing', HI: Astrophysics.HI
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
module.exports = Astrophysics;
|
64
Galaxy.js
Normal file
64
Galaxy.js
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
const PRNG = require('./PRNG');
|
||||||
|
const badwords = require('./badwords');
|
||||||
|
const utils = require('./utils');
|
||||||
|
const Star = require('./Star');
|
||||||
|
|
||||||
|
const spiral_arms = 2;
|
||||||
|
const spiral_angle_degrees = 360;
|
||||||
|
const min_radius = 0.05;
|
||||||
|
const max_radius = 0.9;
|
||||||
|
const thickness = 0.1;
|
||||||
|
const scatter_theta = Math.PI / spiral_arms * 0.2;
|
||||||
|
const scatter_radius = min_radius * 0.4;
|
||||||
|
const spiral_b = spiral_angle_degrees / Math.PI * min_radius / max_radius;
|
||||||
|
const names = [];
|
||||||
|
const rejects = { badwords: 0, duplicates: 0 };
|
||||||
|
|
||||||
|
class Galaxy {
|
||||||
|
constructor(seed, number_of_stars) {
|
||||||
|
this.stars = [];
|
||||||
|
|
||||||
|
let i;
|
||||||
|
let position;
|
||||||
|
|
||||||
|
let pseudoRandom = new PRNG(seed);
|
||||||
|
|
||||||
|
for (i = 0; i < number_of_stars; i++) {
|
||||||
|
let number_of_syllables = Math.floor(pseudoRandom.value() * 2 + 2);
|
||||||
|
let new_name;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
new_name = PRNG.random_name(pseudoRandom, number_of_syllables);
|
||||||
|
|
||||||
|
if (names.indexOf(new_name) >= 0) {
|
||||||
|
rejects.duplicates++;
|
||||||
|
}
|
||||||
|
else if (badwords.indexOf(new_name) >= 0 || badwords.indexContains(new_name) >= 0) {
|
||||||
|
rejects.badwords++
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
names.push(new_name);
|
||||||
|
|
||||||
|
let r = pseudoRandom.realRange(min_radius, max_radius);
|
||||||
|
let theta = spiral_b * Math.log(r / max_radius) + pseudoRandom.gaussrandom(scatter_theta);
|
||||||
|
|
||||||
|
r += pseudoRandom.gaussrandom(scatter_radius);
|
||||||
|
|
||||||
|
theta += pseudoRandom.range(0, spiral_arms - 1) * Math.PI * 2 / spiral_arms;
|
||||||
|
|
||||||
|
position = {
|
||||||
|
x: Math.cos(theta) * r,
|
||||||
|
y: Math.sin(theta) * r,
|
||||||
|
z: pseudoRandom.gaussrandom(thickness * 0.5)
|
||||||
|
};
|
||||||
|
|
||||||
|
this.stars.push(new Star(new_name, pseudoRandom.range(1, 100000), position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Galaxy;
|
123
MersenneTwister.js
Normal file
123
MersenneTwister.js
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
class MersenneTwister {
|
||||||
|
constructor(seed = new Date().getTime()) {
|
||||||
|
this.N = 624;
|
||||||
|
this.M = 397;
|
||||||
|
this.MATRIX_A = 0x9908b0df;
|
||||||
|
this.UPPER_MASK = 0x80000000;
|
||||||
|
this.LOWER_MASK = 0x7fffffff;
|
||||||
|
this.mt = new Array(this.N);
|
||||||
|
this.mti = this.N + 1;
|
||||||
|
|
||||||
|
this.init_genrand(seed);
|
||||||
|
};
|
||||||
|
|
||||||
|
init_genrand(s) {
|
||||||
|
this.mt[0] = s >>> 0;
|
||||||
|
|
||||||
|
for (this.mti = 1; this.mti < this.N; this.mti++) {
|
||||||
|
let s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30);
|
||||||
|
this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) + this.mti;
|
||||||
|
this.mt[this.mti] >>>= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_by_array(init_key, key_length) {
|
||||||
|
let i, j, k;
|
||||||
|
|
||||||
|
this.init_genrand(19650218);
|
||||||
|
|
||||||
|
i = 1;
|
||||||
|
j = 0;
|
||||||
|
k = (this.N > key_length ? this.N : key_length);
|
||||||
|
|
||||||
|
for (; k; k--) {
|
||||||
|
let s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30)
|
||||||
|
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) + init_key[j] + j;
|
||||||
|
this.mt[i] >>>= 0;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
if (i >= this.N) {
|
||||||
|
this.mt[0] = this.mt[this.N - 1];
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j >= key_length) j = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k = this.N - 1; k; k--) {
|
||||||
|
let s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
|
||||||
|
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) - i;
|
||||||
|
this.mt[i] >>>= 0;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i >= this.N) {
|
||||||
|
this.mt[0] = this.mt[this.N - 1];
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mt[0] = 0x80000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
genrand_int32() {
|
||||||
|
let y;
|
||||||
|
let mag01 = new Array(0x0, this.MATRIX_A);
|
||||||
|
|
||||||
|
if (this.mti >= this.N) {
|
||||||
|
let kk;
|
||||||
|
|
||||||
|
if (this.mti == this.N + 1) {
|
||||||
|
this.init_genrand(5489);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (kk = 0; kk < this.N - this.M; kk++) {
|
||||||
|
y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK);
|
||||||
|
this.mt[kk] = this.mt[kk + this.M] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; kk < this.N - 1; kk++) {
|
||||||
|
y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK);
|
||||||
|
this.mt[kk] = this.mt[kk + (this.M - this.N)] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
}
|
||||||
|
|
||||||
|
y = (this.mt[this.N - 1] & this.UPPER_MASK) | (this.mt[0] & this.LOWER_MASK);
|
||||||
|
this.mt[this.N - 1] = this.mt[this.M - 1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
this.mti = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
y = this.mt[this.mti++];
|
||||||
|
y ^= (y >>> 11);
|
||||||
|
y ^= (y << 7) & 0x9d2c5680;
|
||||||
|
y ^= (y << 15) & 0xefc60000;
|
||||||
|
y ^= (y >>> 18);
|
||||||
|
|
||||||
|
return y >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
genrand_int31() {
|
||||||
|
return (this.genrand_int32() >>> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
genrand_real1() {
|
||||||
|
return this.genrand_int32() * (1.0 / 4294967295.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
random() {
|
||||||
|
return this.genrand_int32() * (1.0 / 4294967296.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
genrand_real3() {
|
||||||
|
return (this.genrand_int32() + 0.5) * (1.0 / 4294967296.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
genrand_res53() {
|
||||||
|
let a = this.genrand_int32() >>> 5,
|
||||||
|
b = this.genrand_int32() >>> 6;
|
||||||
|
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = MersenneTwister;
|
122
PRNG.js
Normal file
122
PRNG.js
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
const MersenneTwister = require('./MersenneTwister');
|
||||||
|
|
||||||
|
const name_parts = {
|
||||||
|
prefix: ['a', 'aeg', 'ai', 'alf', 'alph', 'amn', 'an', 'and', 'apt', 'arct', 'ard', 'ath', 'aur', 'b', 'bell', 'bet', 'bor', 'c', 'call', 'can', 'canc', 'cap', 'ceph', 'ch', 'chl', 'cr', 'cz', 'delt', 'drac', 'e', 'eps', 'f', 'fom', 'g', 'gamm', 'gall', 'gat', 'gemi', 'gn', 'gr', 'h', 'heph', 'her', 'holl', 'i', 'in', 'ind', 'ir', 'j', 'k', 'kn', 'l', 'lep', 'lin', 'lov', 'm', 'malth', 'mar', 'med', 'mir', 'mirc', 'n', 'nept', 'o', 'or', 'pers', 'p', 'ph', 'plei', 'plut', 'pn', 'poll', 'pr', 'ps', 'pt', 'pyr', 'q', 'qu', 'r', 'rig', 's', 'sag', 'sc', 'sir', 'str', 't', 'taur', 'tell', 'th', 'tn', 'trop', 'ts', 'u', 'ull', 'ult', 'ur', 'v', 'veg', 'vesp', 'vr', 'w', 'wh', 'wr', 'x', 'xz', 'y', 'z', 'z'],
|
||||||
|
middle: ['acl', 'ac', 'ad', 'aedr', 'agg', 'al', 'alh', 'alr', 'alt', 'am', 'an', 'apr', 'aqu', 'ar', 'ath', 'cul', 'e', 'ec', 'ed', 'ef', 'egg', 'elg', 'em', 'en', 'eph', 'er', 'et', 'i', 'iat', 'ib', 'ic', 'id', 'ig', 'il', 'ir', 'isc', 'ist', 'itt', 'od', 'of', 'om', 'on', 'oph', 'opt', 'orp', 'om', 'oth', 'ue', 'ulp', 'ulph', 'ur', 'und', 'us', 'ut', 'uu'],
|
||||||
|
suffix: ['a', 'ae', 'ai', 'anae', 'ao', 'ar', 'arn', 'aur', 'aut', 'ea', 'ei', 'el', 'eo', 'eon', 'eos', 'es', 'ga', 'ho', 'holm', 'hus', 'i', 'ia', 'iea', 'ii', 'io', 'ion', 'is', 'las', 'o', 'oe', 'oea', 'oi', 'oia', 'on', 'one', 'or', 'orn', 'os', 'ov', 'ova', 'u', 'ua', 'ue', 'ula', 'uo', 'um', 'un', 'us', 'ux', 'z'],
|
||||||
|
secondary: ['Major', 'Minor', 'Secundus', 'Tertius', 'Quartus', 'Quintus', 'Septimus', 'Octavus', 'Nonus', 'Decimus']
|
||||||
|
};
|
||||||
|
|
||||||
|
class PRNG {
|
||||||
|
constructor(seed) {
|
||||||
|
this.mt = new MersenneTwister(seed);
|
||||||
|
};
|
||||||
|
|
||||||
|
value() {
|
||||||
|
return this.mt.random();
|
||||||
|
};
|
||||||
|
|
||||||
|
range(min, max) {
|
||||||
|
return Math.floor(this.value() * (max - min + 1) + min);
|
||||||
|
};
|
||||||
|
|
||||||
|
realRange(min, max, skew_function) {
|
||||||
|
let v = this.value();
|
||||||
|
|
||||||
|
if (typeof skew_function === 'function') {
|
||||||
|
v = skew_function(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v * (max - min) + min;
|
||||||
|
};
|
||||||
|
|
||||||
|
gaussrandom(dev = 1.0) {
|
||||||
|
let X;
|
||||||
|
let context = this.gaussrandom.context;
|
||||||
|
|
||||||
|
if (!context) {
|
||||||
|
context = this.gaussrandom.context = {
|
||||||
|
phase: 0
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (context.phase === 0) {
|
||||||
|
do {
|
||||||
|
context.V1 = this.realRange(-1, 1);
|
||||||
|
context.V2 = this.realRange(-1, 1);
|
||||||
|
context.S = context.V1 * context.V1 + context.V2 * context.V2;
|
||||||
|
}
|
||||||
|
while (context.S >= 1 || context.S == 0);
|
||||||
|
|
||||||
|
X = context.V1 * Math.sqrt(-2 * Math.log(context.S) / context.S);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
X = context.V2 * Math.sqrt(-2 * Math.log(context.S) / context.S);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.phase = 1 - context.phase;
|
||||||
|
|
||||||
|
return X * dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
pick(a, weights) {
|
||||||
|
let s = 0;
|
||||||
|
let idx;
|
||||||
|
|
||||||
|
if (weights !== undefined) {
|
||||||
|
for (idx = 0; idx < weights.length; idx++) {
|
||||||
|
s += weights[idx];
|
||||||
|
}
|
||||||
|
s = this.value() * s;
|
||||||
|
for (idx = 0; idx < weights.length; idx++) {
|
||||||
|
s -= weights[idx];
|
||||||
|
if (s < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idx = this.range(0, a.length - 1);
|
||||||
|
}
|
||||||
|
return a[idx];
|
||||||
|
};
|
||||||
|
|
||||||
|
static random_name(PRNG, number_of_syllables, allow_second_name, allow_secondary) {
|
||||||
|
let syllables = [];
|
||||||
|
let name;
|
||||||
|
let suffix;
|
||||||
|
|
||||||
|
syllables.push(PRNG.pick(name_parts.prefix));
|
||||||
|
|
||||||
|
for (var j = 2; j < number_of_syllables; j++) {
|
||||||
|
syllables.push(PRNG.pick(name_parts.middle));
|
||||||
|
}
|
||||||
|
|
||||||
|
syllables.push(PRNG.pick(name_parts.suffix));
|
||||||
|
|
||||||
|
name = syllables.join('');
|
||||||
|
suffix = PRNG.pick(['', 'first-name', 'second-name', 'secondary'], [8, 1, 1, 4]);
|
||||||
|
|
||||||
|
switch (suffix) {
|
||||||
|
case 'first-name':
|
||||||
|
if (allow_second_name !== false) {
|
||||||
|
name = this.random_name(PRNG, PRNG.range(2, number_of_syllables), false, false).capitalize() + ' ' + name;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'second-name':
|
||||||
|
if (allow_second_name !== false) {
|
||||||
|
name = name + ' ' + this.random_name(PRNG, PRNG.range(2, number_of_syllables), false).capitalize();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'secondary':
|
||||||
|
if (allow_secondary !== false) {
|
||||||
|
name += ' ' + PRNG.pick(name_parts.secondary);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name.capitalize();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PRNG
|
37
Planet.js
Normal file
37
Planet.js
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
const { gravity, blackbody, planetTypeData } = require('./Astrophysics');
|
||||||
|
const PRNG = require('./PRNG');
|
||||||
|
|
||||||
|
class Planet {
|
||||||
|
constructor(name, seed, orbitalRadius, insolation) {
|
||||||
|
this.name = name;
|
||||||
|
this.seed = seed;
|
||||||
|
this.orbitalRadius = orbitalRadius;
|
||||||
|
this.insolation = insolation;
|
||||||
|
|
||||||
|
this.details = this.get_details();
|
||||||
|
};
|
||||||
|
|
||||||
|
get_details() {
|
||||||
|
let pseudoRandom = new PRNG(this.seed);
|
||||||
|
let detail = {};
|
||||||
|
let template;
|
||||||
|
|
||||||
|
template = pseudoRandom.pick(planetTypeData, [this.insolation.toFixed(2) * 100, 10, 1]);
|
||||||
|
detail.name = this.name;
|
||||||
|
detail.orbitalRadius = this.orbitalRadius.toFixed(2);
|
||||||
|
detail.insolation = this.insolation.toFixed(2);
|
||||||
|
detail.blackbodyK = blackbody(detail.insolation);
|
||||||
|
detail.classification = template.classification;
|
||||||
|
detail.radius = pseudoRandom.range(template.radius[0], template.radius[1]);
|
||||||
|
detail.density = pseudoRandom.realRange(template.density[0], template.density[1]);
|
||||||
|
detail.gravity = gravity(detail.radius, detail.density);
|
||||||
|
detail.hydrographics = typeof template.hydrographics === 'function' && template.hydrographics(pseudoRandom, detail.insolation, detail.radius, detail.density);
|
||||||
|
detail.atmosphere = typeof template.atmosphere === 'function' && template.atmosphere(pseudoRandom, detail.insolation, detail.radius, detail.density, detail.hydrographics);
|
||||||
|
|
||||||
|
Object.assign(detail, template.HI(detail.insolation, detail.radius, detail.density, detail.hydrographics, detail.atmosphere));
|
||||||
|
|
||||||
|
return detail;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Planet;
|
75
Star.js
Normal file
75
Star.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
const Planet = require('./Planet');
|
||||||
|
const PRNG = require('./PRNG');
|
||||||
|
const { starTypeData } = require('./Astrophysics');
|
||||||
|
|
||||||
|
class Star {
|
||||||
|
constructor(name, seed, position) {
|
||||||
|
this.name = name;
|
||||||
|
this.seed = seed;
|
||||||
|
this.position = position;
|
||||||
|
|
||||||
|
this.position.far_x = (this.position.x * 50000).toFixed(2);
|
||||||
|
this.position.far_y = (this.position.y * 50000).toFixed(2);
|
||||||
|
this.position.far_z = (this.position.z * 50000).toFixed(2);
|
||||||
|
|
||||||
|
let details = this.get_details();
|
||||||
|
this.radius = Math.max(Math.min(Math.log(details.luminosity) + 8, 20), 2);
|
||||||
|
this.color = details.template.color;
|
||||||
|
|
||||||
|
this.details = details;
|
||||||
|
this.planets = this.get_planets();
|
||||||
|
};
|
||||||
|
|
||||||
|
romanNumeral(n) {
|
||||||
|
const units = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'];
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return '';
|
||||||
|
} else if (n < 0 || n >= 20) {
|
||||||
|
return n;
|
||||||
|
} else if (n >= 10) {
|
||||||
|
return 'X' + this.romanNumeral(n - 10);
|
||||||
|
} else {
|
||||||
|
return units[n - 1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
get_details() {
|
||||||
|
let detail = {};
|
||||||
|
|
||||||
|
let pseudoRandom = new PRNG(this.seed);
|
||||||
|
let spectralClass = pseudoRandom.pick(['O', 'B', 'A', 'F', 'G', 'K', 'M'], [0.0001, 0.2, 1, 3, 8, 12, 20]);
|
||||||
|
let spectralIndex = pseudoRandom.range(0, 9);
|
||||||
|
let stellarTemplate = starTypeData[spectralClass];
|
||||||
|
|
||||||
|
detail.spectralType = spectralClass + spectralIndex;
|
||||||
|
detail.luminosity = stellarTemplate.luminosity * (4 / (spectralIndex + 2));
|
||||||
|
detail.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1]);
|
||||||
|
detail.planetSeed = pseudoRandom.range(0, 1000000);
|
||||||
|
detail.template = stellarTemplate;
|
||||||
|
|
||||||
|
return detail;
|
||||||
|
};
|
||||||
|
|
||||||
|
get_planets() {
|
||||||
|
let details = this.details;
|
||||||
|
let planets = [];
|
||||||
|
let pseudoRandom = new PRNG(details.planetSeed);
|
||||||
|
let radius_min = 0.4 * pseudoRandom.realRange(0.5, 2);
|
||||||
|
let radius_max = 50 * pseudoRandom.realRange(0.5, 2);
|
||||||
|
let total_weight = (Math.pow(details.numberOfPlanets, 2) + details.numberOfPlanets) * 0.5;
|
||||||
|
let r = radius_min;
|
||||||
|
|
||||||
|
for (let i = 0; i < details.numberOfPlanets; i++) {
|
||||||
|
r += i / total_weight * pseudoRandom.realRange(0.5, 1) * (radius_max - radius_min);
|
||||||
|
|
||||||
|
planets.push(
|
||||||
|
new Planet(this.name.capitalize() + '-' + this.romanNumeral(i + 1), pseudoRandom.range(0, 100000), r, details.luminosity / Math.pow(r, 2))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return planets;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Star;
|
453
badwords.json
Normal file
453
badwords.json
Normal file
|
@ -0,0 +1,453 @@
|
||||||
|
[
|
||||||
|
"4r5e",
|
||||||
|
"5h1t",
|
||||||
|
"5hit",
|
||||||
|
"a55",
|
||||||
|
"anal",
|
||||||
|
"anus",
|
||||||
|
"ar5e",
|
||||||
|
"arrse",
|
||||||
|
"arse",
|
||||||
|
"ass",
|
||||||
|
"ass-fucker",
|
||||||
|
"asses",
|
||||||
|
"assfucker",
|
||||||
|
"assfukka",
|
||||||
|
"asshole",
|
||||||
|
"assholes",
|
||||||
|
"asswhole",
|
||||||
|
"a_s_s",
|
||||||
|
"b!tch",
|
||||||
|
"b00bs",
|
||||||
|
"b17ch",
|
||||||
|
"b1tch",
|
||||||
|
"ballbag",
|
||||||
|
"balls",
|
||||||
|
"ballsack",
|
||||||
|
"bastard",
|
||||||
|
"beastial",
|
||||||
|
"beastiality",
|
||||||
|
"bellend",
|
||||||
|
"bestial",
|
||||||
|
"bestiality",
|
||||||
|
"bi+ch",
|
||||||
|
"biatch",
|
||||||
|
"bitch",
|
||||||
|
"bitcher",
|
||||||
|
"bitchers",
|
||||||
|
"bitches",
|
||||||
|
"bitchin",
|
||||||
|
"bitching",
|
||||||
|
"bloody",
|
||||||
|
"blowjob",
|
||||||
|
"blowjob",
|
||||||
|
"blowjobs",
|
||||||
|
"boiolas",
|
||||||
|
"bollock",
|
||||||
|
"bollok",
|
||||||
|
"boner",
|
||||||
|
"boob",
|
||||||
|
"boobs",
|
||||||
|
"booobs",
|
||||||
|
"boooobs",
|
||||||
|
"booooobs",
|
||||||
|
"booooooobs",
|
||||||
|
"breasts",
|
||||||
|
"buceta",
|
||||||
|
"bugger",
|
||||||
|
"bum",
|
||||||
|
"bunnyfucker",
|
||||||
|
"butt",
|
||||||
|
"butthole",
|
||||||
|
"buttmuch",
|
||||||
|
"buttplug",
|
||||||
|
"c0ck",
|
||||||
|
"c0cksucker",
|
||||||
|
"carpetmuncher",
|
||||||
|
"cawk",
|
||||||
|
"chink",
|
||||||
|
"cipa",
|
||||||
|
"cl1t",
|
||||||
|
"clit",
|
||||||
|
"clitoris",
|
||||||
|
"clits",
|
||||||
|
"cnut",
|
||||||
|
"cock",
|
||||||
|
"cock-sucker",
|
||||||
|
"cockface",
|
||||||
|
"cockhead",
|
||||||
|
"cockmunch",
|
||||||
|
"cockmuncher",
|
||||||
|
"cocks",
|
||||||
|
"cocksuck",
|
||||||
|
"cocksucked",
|
||||||
|
"cocksucker",
|
||||||
|
"cocksucking",
|
||||||
|
"cocksucks",
|
||||||
|
"cocksuka",
|
||||||
|
"cocksukka",
|
||||||
|
"cok",
|
||||||
|
"cokmuncher",
|
||||||
|
"coksucka",
|
||||||
|
"coon",
|
||||||
|
"cox",
|
||||||
|
"crap",
|
||||||
|
"cum",
|
||||||
|
"cummer",
|
||||||
|
"cumming",
|
||||||
|
"cums",
|
||||||
|
"cumshot",
|
||||||
|
"cunilingus",
|
||||||
|
"cunillingus",
|
||||||
|
"cunnilingus",
|
||||||
|
"cunt",
|
||||||
|
"cuntlick",
|
||||||
|
"cuntlicker",
|
||||||
|
"cuntlicking",
|
||||||
|
"cunts",
|
||||||
|
"cyalis",
|
||||||
|
"cyberfuc",
|
||||||
|
"cyberfuck",
|
||||||
|
"cyberfucked",
|
||||||
|
"cyberfucker",
|
||||||
|
"cyberfuckers",
|
||||||
|
"cyberfucking",
|
||||||
|
"d1ck",
|
||||||
|
"damn",
|
||||||
|
"dick",
|
||||||
|
"dickhead",
|
||||||
|
"dildo",
|
||||||
|
"dildos",
|
||||||
|
"dink",
|
||||||
|
"dinks",
|
||||||
|
"dirsa",
|
||||||
|
"dlck",
|
||||||
|
"dog-fucker",
|
||||||
|
"doggin",
|
||||||
|
"dogging",
|
||||||
|
"donkeyribber",
|
||||||
|
"doosh",
|
||||||
|
"duche",
|
||||||
|
"dyke",
|
||||||
|
"ejaculate",
|
||||||
|
"ejaculated",
|
||||||
|
"ejaculates",
|
||||||
|
"ejaculating",
|
||||||
|
"ejaculatings",
|
||||||
|
"ejaculation",
|
||||||
|
"ejakulate",
|
||||||
|
"fuck",
|
||||||
|
"fucker",
|
||||||
|
"f4nny",
|
||||||
|
"fag",
|
||||||
|
"fagging",
|
||||||
|
"faggitt",
|
||||||
|
"faggot",
|
||||||
|
"faggs",
|
||||||
|
"fagot",
|
||||||
|
"fagots",
|
||||||
|
"fags",
|
||||||
|
"fanny",
|
||||||
|
"fannyflaps",
|
||||||
|
"fannyfucker",
|
||||||
|
"fanyy",
|
||||||
|
"fatass",
|
||||||
|
"fcuk",
|
||||||
|
"fcuker",
|
||||||
|
"fcuking",
|
||||||
|
"feck",
|
||||||
|
"fecker",
|
||||||
|
"felching",
|
||||||
|
"fellate",
|
||||||
|
"fellatio",
|
||||||
|
"fingerfuck",
|
||||||
|
"fingerfucked",
|
||||||
|
"fingerfucker",
|
||||||
|
"fingerfuckers",
|
||||||
|
"fingerfucking",
|
||||||
|
"fingerfucks",
|
||||||
|
"fistfuck",
|
||||||
|
"fistfucked",
|
||||||
|
"fistfucker",
|
||||||
|
"fistfuckers",
|
||||||
|
"fistfucking",
|
||||||
|
"fistfuckings",
|
||||||
|
"fistfucks",
|
||||||
|
"flange",
|
||||||
|
"fook",
|
||||||
|
"fooker",
|
||||||
|
"fuck",
|
||||||
|
"fucka",
|
||||||
|
"fucked",
|
||||||
|
"fucker",
|
||||||
|
"fuckers",
|
||||||
|
"fuckhead",
|
||||||
|
"fuckheads",
|
||||||
|
"fuckin",
|
||||||
|
"fucking",
|
||||||
|
"fuckings",
|
||||||
|
"fuckingshitmotherfucker",
|
||||||
|
"fuckme",
|
||||||
|
"fucks",
|
||||||
|
"fuckwhit",
|
||||||
|
"fuckwit",
|
||||||
|
"fudgepacker",
|
||||||
|
"fudgepacker",
|
||||||
|
"fuk",
|
||||||
|
"fuker",
|
||||||
|
"fukker",
|
||||||
|
"fukkin",
|
||||||
|
"fuks",
|
||||||
|
"fukwhit",
|
||||||
|
"fukwit",
|
||||||
|
"fux",
|
||||||
|
"fux0r",
|
||||||
|
"f_u_c_k",
|
||||||
|
"gangbang",
|
||||||
|
"gangbanged",
|
||||||
|
"gangbangs",
|
||||||
|
"gaylord",
|
||||||
|
"gaysex",
|
||||||
|
"goatse",
|
||||||
|
"God",
|
||||||
|
"god-dam",
|
||||||
|
"god-damned",
|
||||||
|
"goddamn",
|
||||||
|
"goddamned",
|
||||||
|
"hardcoresex",
|
||||||
|
"hell",
|
||||||
|
"heshe",
|
||||||
|
"hoar",
|
||||||
|
"hoare",
|
||||||
|
"hoer",
|
||||||
|
"homo",
|
||||||
|
"hore",
|
||||||
|
"horniest",
|
||||||
|
"horny",
|
||||||
|
"hotsex",
|
||||||
|
"jack-off",
|
||||||
|
"jackoff",
|
||||||
|
"jap",
|
||||||
|
"jerk-off",
|
||||||
|
"jism",
|
||||||
|
"jiz",
|
||||||
|
"jizm",
|
||||||
|
"jizz",
|
||||||
|
"kawk",
|
||||||
|
"knob",
|
||||||
|
"knobead",
|
||||||
|
"knobed",
|
||||||
|
"knobend",
|
||||||
|
"knobhead",
|
||||||
|
"knobjocky",
|
||||||
|
"knobjokey",
|
||||||
|
"kock",
|
||||||
|
"kondum",
|
||||||
|
"kondums",
|
||||||
|
"kum",
|
||||||
|
"kummer",
|
||||||
|
"kumming",
|
||||||
|
"kums",
|
||||||
|
"kunilingus",
|
||||||
|
"l3i+ch",
|
||||||
|
"l3itch",
|
||||||
|
"labia",
|
||||||
|
"lmfao",
|
||||||
|
"lust",
|
||||||
|
"lusting",
|
||||||
|
"m0f0",
|
||||||
|
"m0fo",
|
||||||
|
"m45terbate",
|
||||||
|
"ma5terb8",
|
||||||
|
"ma5terbate",
|
||||||
|
"masochist",
|
||||||
|
"master-bate",
|
||||||
|
"masterb8",
|
||||||
|
"masterbat*",
|
||||||
|
"masterbat3",
|
||||||
|
"masterbate",
|
||||||
|
"masterbation",
|
||||||
|
"masterbations",
|
||||||
|
"masturbate",
|
||||||
|
"mo-fo",
|
||||||
|
"mof0",
|
||||||
|
"mofo",
|
||||||
|
"mothafuck",
|
||||||
|
"mothafucka",
|
||||||
|
"mothafuckas",
|
||||||
|
"mothafuckaz",
|
||||||
|
"mothafucked",
|
||||||
|
"mothafucker",
|
||||||
|
"mothafuckers",
|
||||||
|
"mothafuckin",
|
||||||
|
"mothafucking",
|
||||||
|
"mothafuckings",
|
||||||
|
"mothafucks",
|
||||||
|
"motherfucker",
|
||||||
|
"motherfuck",
|
||||||
|
"motherfucked",
|
||||||
|
"motherfucker",
|
||||||
|
"motherfuckers",
|
||||||
|
"motherfuckin",
|
||||||
|
"motherfucking",
|
||||||
|
"motherfuckings",
|
||||||
|
"motherfuckka",
|
||||||
|
"motherfucks",
|
||||||
|
"muff",
|
||||||
|
"mutha",
|
||||||
|
"muthafecker",
|
||||||
|
"muthafuckker",
|
||||||
|
"muther",
|
||||||
|
"mutherfucker",
|
||||||
|
"n1gga",
|
||||||
|
"n1gger",
|
||||||
|
"nazi",
|
||||||
|
"nigg3r",
|
||||||
|
"nigg4h",
|
||||||
|
"nigga",
|
||||||
|
"niggah",
|
||||||
|
"niggas",
|
||||||
|
"niggaz",
|
||||||
|
"nigger",
|
||||||
|
"niggers",
|
||||||
|
"nob",
|
||||||
|
"nobjokey",
|
||||||
|
"nobhead",
|
||||||
|
"nobjocky",
|
||||||
|
"nobjokey",
|
||||||
|
"numbnuts",
|
||||||
|
"nutsack",
|
||||||
|
"orgasim",
|
||||||
|
"orgasims",
|
||||||
|
"orgasm",
|
||||||
|
"orgasms",
|
||||||
|
"p0rn",
|
||||||
|
"pawn",
|
||||||
|
"pecker",
|
||||||
|
"penis",
|
||||||
|
"penisfucker",
|
||||||
|
"phonesex",
|
||||||
|
"phuck",
|
||||||
|
"phuk",
|
||||||
|
"phuked",
|
||||||
|
"phuking",
|
||||||
|
"phukked",
|
||||||
|
"phukking",
|
||||||
|
"phuks",
|
||||||
|
"phuq",
|
||||||
|
"pigfucker",
|
||||||
|
"pimpis",
|
||||||
|
"piss",
|
||||||
|
"pissed",
|
||||||
|
"pisser",
|
||||||
|
"pissers",
|
||||||
|
"pisses",
|
||||||
|
"pissflaps",
|
||||||
|
"pissin",
|
||||||
|
"pissing",
|
||||||
|
"pissoff",
|
||||||
|
"poop",
|
||||||
|
"porn",
|
||||||
|
"porno",
|
||||||
|
"pornography",
|
||||||
|
"pornos",
|
||||||
|
"prick",
|
||||||
|
"pricks",
|
||||||
|
"pron",
|
||||||
|
"pube",
|
||||||
|
"pusse",
|
||||||
|
"pussi",
|
||||||
|
"pussies",
|
||||||
|
"pussy",
|
||||||
|
"pussys",
|
||||||
|
"rectum",
|
||||||
|
"retard",
|
||||||
|
"rimjaw",
|
||||||
|
"rimming",
|
||||||
|
"shit",
|
||||||
|
"s.o.b.",
|
||||||
|
"sadist",
|
||||||
|
"schlong",
|
||||||
|
"screwing",
|
||||||
|
"scroat",
|
||||||
|
"scrote",
|
||||||
|
"scrotum",
|
||||||
|
"semen",
|
||||||
|
"sex",
|
||||||
|
"sh!+",
|
||||||
|
"sh!t",
|
||||||
|
"sh1t",
|
||||||
|
"shag",
|
||||||
|
"shagger",
|
||||||
|
"shaggin",
|
||||||
|
"shagging",
|
||||||
|
"shemale",
|
||||||
|
"shi+",
|
||||||
|
"shit",
|
||||||
|
"shitdick",
|
||||||
|
"shite",
|
||||||
|
"shited",
|
||||||
|
"shitey",
|
||||||
|
"shitfuck",
|
||||||
|
"shitfull",
|
||||||
|
"shithead",
|
||||||
|
"shiting",
|
||||||
|
"shitings",
|
||||||
|
"shits",
|
||||||
|
"shitted",
|
||||||
|
"shitter",
|
||||||
|
"shitters",
|
||||||
|
"shitting",
|
||||||
|
"shittings",
|
||||||
|
"shitty",
|
||||||
|
"skank",
|
||||||
|
"slut",
|
||||||
|
"sluts",
|
||||||
|
"smegma",
|
||||||
|
"smut",
|
||||||
|
"snatch",
|
||||||
|
"son-of-a-bitch",
|
||||||
|
"spac",
|
||||||
|
"spunk",
|
||||||
|
"s_h_i_t",
|
||||||
|
"t1tt1e5",
|
||||||
|
"t1tties",
|
||||||
|
"teets",
|
||||||
|
"teez",
|
||||||
|
"testical",
|
||||||
|
"testicle",
|
||||||
|
"tit",
|
||||||
|
"titfuck",
|
||||||
|
"tits",
|
||||||
|
"titt",
|
||||||
|
"tittie5",
|
||||||
|
"tittiefucker",
|
||||||
|
"titties",
|
||||||
|
"tittyfuck",
|
||||||
|
"tittywank",
|
||||||
|
"titwank",
|
||||||
|
"tosser",
|
||||||
|
"turd",
|
||||||
|
"tw4t",
|
||||||
|
"twat",
|
||||||
|
"twathead",
|
||||||
|
"twatty",
|
||||||
|
"twunt",
|
||||||
|
"twunter",
|
||||||
|
"v14gra",
|
||||||
|
"v1gra",
|
||||||
|
"vagina",
|
||||||
|
"viagra",
|
||||||
|
"vulva",
|
||||||
|
"w00se",
|
||||||
|
"wang",
|
||||||
|
"wank",
|
||||||
|
"wanker",
|
||||||
|
"wanky",
|
||||||
|
"whoar",
|
||||||
|
"whore",
|
||||||
|
"willies",
|
||||||
|
"willy",
|
||||||
|
"xrated",
|
||||||
|
"xxx"
|
||||||
|
]
|
51
data.json
51
data.json
|
@ -1,51 +0,0 @@
|
||||||
{
|
|
||||||
"starTypes": {
|
|
||||||
"O": {
|
|
||||||
"luminosity": 50000,
|
|
||||||
"color": [192, 128, 255],
|
|
||||||
"planets": [0, 3]
|
|
||||||
},
|
|
||||||
"B": {
|
|
||||||
"luminosity": 15000,
|
|
||||||
"color": [128, 192, 255],
|
|
||||||
"planets": [1, 5]
|
|
||||||
},
|
|
||||||
"A": {
|
|
||||||
"luminosity": 25,
|
|
||||||
"color": [128, 192, 255],
|
|
||||||
"planets": [1, 7]
|
|
||||||
},
|
|
||||||
"F": {
|
|
||||||
"luminosity": 2.5,
|
|
||||||
"color": [220, 255, 192],
|
|
||||||
"planets": [1, 11]
|
|
||||||
},
|
|
||||||
"G": {
|
|
||||||
"luminosity": 1,
|
|
||||||
"color": [255, 192, 64],
|
|
||||||
"planets": [1, 19]
|
|
||||||
},
|
|
||||||
"K": {
|
|
||||||
"luminosity": 0.25,
|
|
||||||
"color": [255, 128, 64],
|
|
||||||
"planets": [1, 9]
|
|
||||||
},
|
|
||||||
"M": {
|
|
||||||
"luminosity": 0.05,
|
|
||||||
"color": [255, 100, 0],
|
|
||||||
"planets": [1, 5]
|
|
||||||
},
|
|
||||||
"black hole": {
|
|
||||||
"luminosity": 100000,
|
|
||||||
"color": [128, 0, 64],
|
|
||||||
"planets": [0, 0]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nameParts": {
|
|
||||||
"prefix": ["a", "aeg", "ai", "alf", "alph", "amn", "an", "and", "apt", "arct", "ard", "ath", "aur", "b", "bell", "bet", "bor", "c", "call", "can", "canc", "cap", "ceph", "ch", "chl", "cr", "cz", "delt", "drac", "e", "eps", "f", "fom", "g", "gamm", "gall", "gat", "gemi", "gn", "gr", "h", "heph", "her", "holl", "i", "in", "ind", "ir", "j", "k", "kn", "l", "lep", "lin", "lov", "m", "malth", "mar", "med", "mir", "mirc", "n", "nept", "o", "or", "pers", "p", "ph", "plei", "plut", "pn", "poll", "pr", "ps", "pt", "pyr", "q", "qu", "r", "rig", "s", "sag", "sc", "sir", "str", "t", "taur", "tell", "th", "tn", "trop", "ts", "u", "ull", "ult", "ur", "v", "veg", "vesp", "vr", "w", "wh", "wr", "x", "xz", "y", "z", "z"],
|
|
||||||
"middle": ["acl", "ac", "ad", "aedr", "agg", "al", "alh", "alr", "alt", "am", "an", "apr", "aqu", "ar", "ath", "cul", "e", "ec", "ed", "ef", "egg", "elg", "em", "en", "eph", "er", "et", "i", "iat", "ib", "ic", "id", "ig", "il", "ir", "isc", "ist", "itt", "od", "of", "om", "on", "oph", "opt", "orp", "om", "oth", "ue", "ulp", "ulph", "ur", "und", "us", "ut", "uu"],
|
|
||||||
"suffix": ["a", "ae", "ai", "anae", "ao", "ar", "arn", "aur", "aut", "ea", "ei", "el", "eo", "eon", "eos", "es", "ga", "ho", "holm", "hus", "i", "ia", "iea", "ii", "io", "ion", "is", "las", "o", "oe", "oea", "oi", "oia", "on", "one", "or", "orn", "os", "ov", "ova", "u", "ua", "ue", "ula", "uo", "um", "un", "us", "ux", "z"],
|
|
||||||
"secondary": ["Major", "Minor", "Secundus", "Tertius", "Quartus", "Quintus", "Septimus", "Octavus", "Nonus", "Decimus"]
|
|
||||||
},
|
|
||||||
"badwords": ["4r5e", "5h1t", "5hit", "a55", "anal", "anus", "ar5e", "arrse", "arse", "ass", "ass-fucker", "asses", "assfucker", "assfukka", "asshole", "assholes", "asswhole", "a_s_s", "b!tch", "b00bs", "b17ch", "b1tch", "ballbag", "balls", "ballsack", "bastard", "beastial", "beastiality", "bellend", "bestial", "bestiality", "bi+ch", "biatch", "bitch", "bitcher", "bitchers", "bitches", "bitchin", "bitching", "bloody", "blowjob", "blowjob", "blowjobs", "boiolas", "bollock", "bollok", "boner", "boob", "boobs", "booobs", "boooobs", "booooobs", "booooooobs", "breasts", "buceta", "bugger", "bum", "bunnyfucker", "butt", "butthole", "buttmuch", "buttplug", "c0ck", "c0cksucker", "carpetmuncher", "cawk", "chink", "cipa", "cl1t", "clit", "clitoris", "clits", "cnut", "cock", "cock-sucker", "cockface", "cockhead", "cockmunch", "cockmuncher", "cocks", "cocksuck", "cocksucked", "cocksucker", "cocksucking", "cocksucks", "cocksuka", "cocksukka", "cok", "cokmuncher", "coksucka", "coon", "cox", "crap", "cum", "cummer", "cumming", "cums", "cumshot", "cunilingus", "cunillingus", "cunnilingus", "cunt", "cuntlick", "cuntlicker", "cuntlicking", "cunts", "cyalis", "cyberfuc", "cyberfuck", "cyberfucked", "cyberfucker", "cyberfuckers", "cyberfucking", "d1ck", "damn", "dick", "dickhead", "dildo", "dildos", "dink", "dinks", "dirsa", "dlck", "dog-fucker", "doggin", "dogging", "donkeyribber", "doosh", "duche", "dyke", "ejaculate", "ejaculated", "ejaculates", "ejaculating", "ejaculatings", "ejaculation", "ejakulate", "fuck", "fucker", "f4nny", "fag", "fagging", "faggitt", "faggot", "faggs", "fagot", "fagots", "fags", "fanny", "fannyflaps", "fannyfucker", "fanyy", "fatass", "fcuk", "fcuker", "fcuking", "feck", "fecker", "felching", "fellate", "fellatio", "fingerfuck", "fingerfucked", "fingerfucker", "fingerfuckers", "fingerfucking", "fingerfucks", "fistfuck", "fistfucked", "fistfucker", "fistfuckers", "fistfucking", "fistfuckings", "fistfucks", "flange", "fook", "fooker", "fuck", "fucka", "fucked", "fucker", "fuckers", "fuckhead", "fuckheads", "fuckin", "fucking", "fuckings", "fuckingshitmotherfucker", "fuckme", "fucks", "fuckwhit", "fuckwit", "fudgepacker", "fudgepacker", "fuk", "fuker", "fukker", "fukkin", "fuks", "fukwhit", "fukwit", "fux", "fux0r", "f_u_c_k", "gangbang", "gangbanged", "gangbangs", "gaylord", "gaysex", "goatse", "God", "god-dam", "god-damned", "goddamn", "goddamned", "hardcoresex", "hell", "heshe", "hoar", "hoare", "hoer", "homo", "hore", "horniest", "horny", "hotsex", "jack-off", "jackoff", "jap", "jerk-off", "jism", "jiz", "jizm", "jizz", "kawk", "knob", "knobead", "knobed", "knobend", "knobhead", "knobjocky", "knobjokey", "kock", "kondum", "kondums", "kum", "kummer", "kumming", "kums", "kunilingus", "l3i+ch", "l3itch", "labia", "lmfao", "lust", "lusting", "m0f0", "m0fo", "m45terbate", "ma5terb8", "ma5terbate", "masochist", "master-bate", "masterb8", "masterbat*", "masterbat3", "masterbate", "masterbation", "masterbations", "masturbate", "mo-fo", "mof0", "mofo", "mothafuck", "mothafucka", "mothafuckas", "mothafuckaz", "mothafucked", "mothafucker", "mothafuckers", "mothafuckin", "mothafucking", "mothafuckings", "mothafucks", "motherfucker", "motherfuck", "motherfucked", "motherfucker", "motherfuckers", "motherfuckin", "motherfucking", "motherfuckings", "motherfuckka", "motherfucks", "muff", "mutha", "muthafecker", "muthafuckker", "muther", "mutherfucker", "n1gga", "n1gger", "nazi", "nigg3r", "nigg4h", "nigga", "niggah", "niggas", "niggaz", "nigger", "niggers", "nob", "nobjokey", "nobhead", "nobjocky", "nobjokey", "numbnuts", "nutsack", "orgasim", "orgasims", "orgasm", "orgasms", "p0rn", "pawn", "pecker", "penis", "penisfucker", "phonesex", "phuck", "phuk", "phuked", "phuking", "phukked", "phukking", "phuks", "phuq", "pigfucker", "pimpis", "piss", "pissed", "pisser", "pissers", "pisses", "pissflaps", "pissin", "pissing", "pissoff", "poop", "porn", "porno", "pornography", "pornos", "prick", "pricks", "pron", "pube", "pusse", "pussi", "pussies", "pussy", "pussys", "rectum", "retard", "rimjaw", "rimming", "shit", "s.o.b.", "sadist", "schlong", "screwing", "scroat", "scrote", "scrotum", "semen", "sex", "sh!+", "sh!t", "sh1t", "shag", "shagger", "shaggin", "shagging", "shemale", "shi+", "shit", "shitdick", "shite", "shited", "shitey", "shitfuck", "shitfull", "shithead", "shiting", "shitings", "shits", "shitted", "shitter", "shitters", "shitting", "shittings", "shitty", "skank", "slut", "sluts", "smegma", "smut", "snatch", "son-of-a-bitch", "spac", "spunk", "s_h_i_t", "t1tt1e5", "t1tties", "teets", "teez", "testical", "testicle", "tit", "titfuck", "tits", "titt", "tittie5", "tittiefucker", "titties", "tittyfuck", "tittywank", "titwank", "tosser", "turd", "tw4t", "twat", "twathead", "twatty", "twunt", "twunter", "v14gra", "v1gra", "vagina", "viagra", "vulva", "w00se", "wang", "wank", "wanker", "wanky", "whoar", "whore", "willies", "willy", "xrated", "xxx"]
|
|
||||||
}
|
|
37
galaxygen
37
galaxygen
|
@ -1,27 +1,26 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const cli = require('cli');
|
const cli = require('cli');
|
||||||
const galaxy = require('./index');
|
const Galaxy = require('./Galaxy');
|
||||||
|
|
||||||
cli.parse({
|
cli.parse({
|
||||||
seed: ['s', 'The seed you want to generate with. (defaults to \'1234\')', 'string'],
|
seed: ['s', 'The seed you want to generate with. (defaults to \'1234\')', 'string'],
|
||||||
amount: ['a', 'The amount of stars you want to generate. (defaults to 1000)', 'int'],
|
amount: ['a', 'The amount of stars you want to generate. (defaults to 1000)', 'int'],
|
||||||
output: ['o', 'The output file (if enabled). (defaults to printing JSON to stdout)', 'string'],
|
output: ['o', 'The output file (if enabled). (defaults to printing JSON to stdout)', 'string'],
|
||||||
});
|
});
|
||||||
|
|
||||||
cli.main((args, options) => {
|
cli.main((args, options) => {
|
||||||
var gen = galaxy.generate(options.seed, options.amount);
|
let galaxy = new Galaxy(options.seed || ~~(Math.random() * 10000), options.amount || 1000);
|
||||||
|
|
||||||
if (options.output) {
|
|
||||||
fs.access(options.output, fs.R_OK | fs.W_OK, (err) => {
|
|
||||||
if (err) console.log('No write access to the specified output file!');
|
|
||||||
else {
|
|
||||||
fs.writeFileSync(options.output, JSON.stringify(gen, null, 2));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(JSON.stringify(gen, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (options.output) {
|
||||||
|
fs.access(options.output, fs.R_OK | fs.W_OK, (err) => {
|
||||||
|
if (err) console.log('No write access to the specified output file!');
|
||||||
|
else {
|
||||||
|
fs.writeFileSync(options.output, JSON.stringify(galaxy, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(JSON.stringify(galaxy, null, 2));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
74
index.js
74
index.js
|
@ -1,74 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
const PRNG = require('./prng');
|
|
||||||
const Star = require('./star');
|
|
||||||
const utils = require('./utils');
|
|
||||||
const data = require('./data.json');
|
|
||||||
|
|
||||||
var names = [];
|
|
||||||
var stars = [];
|
|
||||||
var planets = [];
|
|
||||||
|
|
||||||
function generate(seed, amount) {
|
|
||||||
if (!amount) amount = 1000;
|
|
||||||
if (!seed) seed = 1234;
|
|
||||||
|
|
||||||
var spiral_arms = 2,
|
|
||||||
spiral_angle_degrees = 360,
|
|
||||||
min_radius = 0.05,
|
|
||||||
max_radius = 0.9,
|
|
||||||
thickness = 0.1,
|
|
||||||
scatter_theta = Math.PI / spiral_arms * 0.2,
|
|
||||||
scatter_radius = min_radius * 0.4,
|
|
||||||
spiral_b = spiral_angle_degrees / Math.PI * min_radius / max_radius,
|
|
||||||
|
|
||||||
start = (new Date()).getTime(),
|
|
||||||
names = [],
|
|
||||||
|
|
||||||
rejects = {
|
|
||||||
badwords: 0,
|
|
||||||
duplicates: 0
|
|
||||||
},
|
|
||||||
|
|
||||||
totalCount = amount,
|
|
||||||
i,
|
|
||||||
position,
|
|
||||||
lastSeed;
|
|
||||||
|
|
||||||
prng = new PRNG(seed);
|
|
||||||
|
|
||||||
for (i = 0; i < totalCount; i++) {
|
|
||||||
var number_of_syllables = Math.floor(prng.value() * 2 + 2), new_name;
|
|
||||||
while (true) {
|
|
||||||
new_name = utils.random_name(prng, number_of_syllables);
|
|
||||||
if (names.indexOf(new_name) >= 0) {
|
|
||||||
rejects.duplicates++;
|
|
||||||
} else if (data.badwords.indexOf(new_name) >= 0 || data.badwords.indexContains(new_name) >= 0) {
|
|
||||||
rejects.badwords++
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
names.push(new_name);
|
|
||||||
var r = prng.realRange(min_radius, max_radius);
|
|
||||||
var theta = spiral_b * Math.log(r / max_radius) + prng.gaussrandom(scatter_theta);
|
|
||||||
r += prng.gaussrandom(scatter_radius);
|
|
||||||
// assign to a spiral arm
|
|
||||||
theta += prng.range(0, spiral_arms - 1) * Math.PI * 2 / spiral_arms;
|
|
||||||
position = {
|
|
||||||
x: (Math.cos(theta) * r) * 100,
|
|
||||||
y: (Math.sin(theta) * r) * 100,
|
|
||||||
z: prng.gaussrandom(thickness * 0.5) * 100
|
|
||||||
};
|
|
||||||
|
|
||||||
//FIXME: For some fucking reason the code only works if I call a prng value right here.
|
|
||||||
prng.value()
|
|
||||||
|
|
||||||
stars.push(new Star(new_name, Math.floor(prng.value() * 100000), position));
|
|
||||||
}
|
|
||||||
|
|
||||||
return stars;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
"generate": generate
|
|
||||||
}
|
|
107
planet.js
107
planet.js
|
@ -1,107 +0,0 @@
|
||||||
const PRNG = require('./prng');
|
|
||||||
const utils = require('./utils');
|
|
||||||
|
|
||||||
function Planet(name, seed, orbitalRadius, insolation, hasStation) {
|
|
||||||
var pseudoRandom = new PRNG(seed),
|
|
||||||
template = pseudoRandom.pick(planetTypes, [insolation * 100, 10, 1]);
|
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.seed = seed;
|
|
||||||
this.orbitalRadius = orbitalRadius * 10;
|
|
||||||
this.insolation = insolation;
|
|
||||||
this.blackbodyK = utils.blackbody(this.insolation);
|
|
||||||
this.temperature = this.blackbodyK - 273.15;
|
|
||||||
this.classification = template.classification;
|
|
||||||
this.radius = pseudoRandom.range(template.radius[0], template.radius[1]) / 2200;
|
|
||||||
this.density = pseudoRandom.realRange(template.density[0], template.density[1]);
|
|
||||||
this.gravity = utils.gravity(this.radius, this.density);
|
|
||||||
this.hydrographics = template.hydrographics(pseudoRandom, this.insolation, this.radius, this.density);
|
|
||||||
this.atmosphere = template.atmosphere(pseudoRandom, this.insolation, this.radius, this.density, this.hydrographics);
|
|
||||||
this.HI = template.HI(this.insolation, this.radius, this.density, this.hydrographics, this.atmosphere);
|
|
||||||
this.habitable = this.HI == 2 && this.temperature > -60 && this.temperature < 60;
|
|
||||||
if (pseudoRandom.value() > .9) this.water = {
|
|
||||||
color: this.generateWaterColor(this.temperature, pseudoRandom)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.color = this.generateColor(this.temperature, this.water, pseudoRandom);
|
|
||||||
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Planet.prototype.generateStation = function (prng) {
|
|
||||||
return {
|
|
||||||
size: prng.pick(['small', 'big', 'epic'], [498, 499, 8]),
|
|
||||||
economy: prng.pick(['mining', 'agricultural', 'tech', 'industrial', 'residential'], [15, 30, 15, 10, 30])
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Planet.prototype.generateColor = function (temperature, water, prng) {
|
|
||||||
if (temperature < 0 && water) {
|
|
||||||
var color = Math.floor(prng.value() * 100) + 155;
|
|
||||||
return [color, color, color];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return [Math.floor(prng.value() * 100) + 125, Math.floor(prng.value() * 100) + 125, Math.floor(prng.value() * 100) + 125];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Planet.prototype.generateWaterColor = function (temperature, prng) {
|
|
||||||
if (temperature > 100) return false;
|
|
||||||
else {
|
|
||||||
return [Math.floor(prng.value() * 60) + 50, Math.floor(prng.value() * 60) + 50, Math.floor(prng.value() * 200) + 55]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var planetTypes = [
|
|
||||||
{
|
|
||||||
classification: "rocky",
|
|
||||||
radius: [1000, 15000],
|
|
||||||
density: [2, 8],
|
|
||||||
hydrographics: function(prng, insolation, radius, density) {
|
|
||||||
var g = utils.gravity(radius, density),
|
|
||||||
tempK = utils.blackbody(insolation, 0);
|
|
||||||
return Math.clamp(prng.realRange(-50, 150 - Math.abs(tempK - 270)) * g - Math.abs(density - 5.5) * 10, 0, 100);
|
|
||||||
},
|
|
||||||
atmosphere: function(prng, insolation, radius, density, hydrographics) {
|
|
||||||
var g = utils.gravity(radius, density);
|
|
||||||
if (hydrographics > 0 && insolation > 0.25 && insolation < 2) {
|
|
||||||
return prng.pick(['Breathable', 'Filterable', 'Inert', 'Toxic', 'Corrosive', 'Trace'], [1, 2, 2, 1, 1, 1]);
|
|
||||||
} else {
|
|
||||||
return prng.pick(['Breathable', 'Filterable', 'Inert', 'Toxic', 'Corrosive', 'Trace'], [1, 2, 3, 4, 5, 5]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
HI: function(insolation, radius, density, hydrographics, atmosphere) {
|
|
||||||
var g = utils.gravity(radius, density),
|
|
||||||
tempK = utils.blackbody(insolation, 0);
|
|
||||||
if (atmosphere === "Breathable" && hydrographics > 0 && g < 1.25 && tempK > 230 && tempK < 280) {
|
|
||||||
return 1;
|
|
||||||
} else if ((atmosphere === "Breathable" || atmosphere === 'Filterable') && g < 2 && tempK > 200 && tempK < 310) {
|
|
||||||
return 2;
|
|
||||||
} else if (atmosphere === "Corrosive" || g > 2 || tempK > 400) {
|
|
||||||
return tempK > 1000 ? 5 : 4;
|
|
||||||
} else {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
classification: "gas giant",
|
|
||||||
radius: [15000, 120000],
|
|
||||||
density: [0.6, 2.0],
|
|
||||||
hydrographics: utils.fixed_value(0),
|
|
||||||
atmosphere: utils.fixed_value("Crushing"),
|
|
||||||
HI: utils.fixed_value(4)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
classification: "brown dwarf",
|
|
||||||
radius: [120000, 250000],
|
|
||||||
density: [0.6, 2.0],
|
|
||||||
hydrographics: utils.fixed_value(0),
|
|
||||||
atmosphere: utils.fixed_value("Crushing"),
|
|
||||||
HI: utils.fixed_value(5)
|
|
||||||
}];
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = Planet;
|
|
73
prng.js
73
prng.js
|
@ -1,73 +0,0 @@
|
||||||
const MersenneTwister = require('./twister');
|
|
||||||
|
|
||||||
function PRNG(seed) {
|
|
||||||
this.mt = new MersenneTwister(seed);
|
|
||||||
this.seed = seed;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
PRNG.prototype.seed = 0;
|
|
||||||
|
|
||||||
PRNG.prototype.value = function() {
|
|
||||||
return this.mt.random()
|
|
||||||
};
|
|
||||||
|
|
||||||
PRNG.prototype.range = function(min, max) {
|
|
||||||
return Math.floor(this.value() * (max - min + 1) + min);
|
|
||||||
};
|
|
||||||
|
|
||||||
PRNG.prototype.realRange = function(min, max, skew_function) {
|
|
||||||
var v = this.value();
|
|
||||||
if (typeof skew_function === 'function') {
|
|
||||||
v = skew_function(v);
|
|
||||||
}
|
|
||||||
return v * (max - min) + min;
|
|
||||||
};
|
|
||||||
|
|
||||||
PRNG.prototype.gaussrandom = function(dev) {
|
|
||||||
var X;
|
|
||||||
var context = this.gaussrandom.context;
|
|
||||||
if (context === undefined) {
|
|
||||||
context = this.gaussrandom.context = {
|
|
||||||
phase: 0
|
|
||||||
};
|
|
||||||
};
|
|
||||||
if (context.phase === 0) {
|
|
||||||
do {
|
|
||||||
context.V1 = this.realRange(-1, 1);
|
|
||||||
context.V2 = this.realRange(-1, 1);
|
|
||||||
context.S = context.V1 * context.V1 + context.V2 * context.V2;
|
|
||||||
} while (context.S >= 1 || context.S == 0);
|
|
||||||
X = context.V1 * Math.sqrt(-2 * Math.log(context.S) / context.S);
|
|
||||||
} else {
|
|
||||||
X = context.V2 * Math.sqrt(-2 * Math.log(context.S) / context.S);
|
|
||||||
}
|
|
||||||
context.phase = 1 - context.phase;
|
|
||||||
if (dev === undefined) {
|
|
||||||
dev = 1.0;
|
|
||||||
}
|
|
||||||
return X * dev;
|
|
||||||
};
|
|
||||||
|
|
||||||
PRNG.prototype.pick = function(a, weights) {
|
|
||||||
var s = 0,
|
|
||||||
idx;
|
|
||||||
if (weights !== undefined) {
|
|
||||||
for (idx = 0; idx < weights.length; idx++) {
|
|
||||||
s += weights[idx];
|
|
||||||
}
|
|
||||||
s = this.value() * s;
|
|
||||||
for (idx = 0; idx < weights.length; idx++) {
|
|
||||||
s -= weights[idx];
|
|
||||||
if (s < 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
idx = this.range(0, a.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return a[idx];
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = PRNG;
|
|
65
star.js
65
star.js
|
@ -1,65 +0,0 @@
|
||||||
const PRNG = require('./prng');
|
|
||||||
const Planet = require('./planet');
|
|
||||||
const utils = require('./utils');
|
|
||||||
const data = require('./data.json');
|
|
||||||
|
|
||||||
function Star(name, seed, position) {
|
|
||||||
var pseudoRandom = new PRNG(seed),
|
|
||||||
spectralClass = pseudoRandom.pick(["black hole", "O", "B", "A", "F", "G", "K", "M"], [.5, 0.0001, 0.2, 1, 3, 8, 12, 20]),
|
|
||||||
spectralIndex = pseudoRandom.range(0, 9),
|
|
||||||
stellarTemplate = data.starTypes[spectralClass];
|
|
||||||
|
|
||||||
this.name = name;
|
|
||||||
this.seed = seed;
|
|
||||||
this.position = position;
|
|
||||||
if (spectralClass != 'black hole')
|
|
||||||
this.spectralType = spectralClass + spectralIndex;
|
|
||||||
else
|
|
||||||
this.spectralType = spectralClass;
|
|
||||||
this.luminosity = stellarTemplate.luminosity * (4 / (spectralIndex + 2)) * 50;
|
|
||||||
this.radius = Math.sqrt(this.luminosity);
|
|
||||||
this.numberOfPlanets = pseudoRandom.range(stellarTemplate.planets[0], stellarTemplate.planets[1]);
|
|
||||||
this.numberOfStations = pseudoRandom.range(0, this.numberOfPlanets / 20);
|
|
||||||
this.planetSeed = pseudoRandom.range(0, 1000000);
|
|
||||||
this.color = stellarTemplate.color;
|
|
||||||
this.planets = this.generatePlanets();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Star.prototype.generatePlanets = function () {
|
|
||||||
var planets = [],
|
|
||||||
pseudoRandom = new PRNG(this.planetSeed),
|
|
||||||
radius_min = 0.4 * pseudoRandom.realRange(0.5, 2),
|
|
||||||
radius_max = 50 * pseudoRandom.realRange(0.5, 2),
|
|
||||||
total_weight = (Math.pow(this.numberOfPlanets, 2) + this.numberOfPlanets) * 0.5,
|
|
||||||
r = radius_min
|
|
||||||
|
|
||||||
for (var i = 0; i < this.numberOfPlanets; i++) {
|
|
||||||
r += i / total_weight * pseudoRandom.realRange(0.5, 1) * (radius_max - radius_min);
|
|
||||||
planets.push(new Planet(utils.kappatalize(this.name) + "-" + utils.romanNumeral(i + 1), pseudoRandom.range(0, 1000000), r, this.luminosity / Math.pow(r, 2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.divideStations(planets, this.seed);
|
|
||||||
|
|
||||||
return planets;
|
|
||||||
}
|
|
||||||
|
|
||||||
Star.prototype.divideStations = function (planets, seed) {
|
|
||||||
var stations = this.numberOfStations || 0;
|
|
||||||
var i = planets.length - 1;
|
|
||||||
var pseudoRandom = new PRNG(seed);
|
|
||||||
|
|
||||||
for (i = 0; i < stations; i++) {
|
|
||||||
var arr = []
|
|
||||||
for (planet of planets) {
|
|
||||||
arr.push(100 / planets.length);
|
|
||||||
}
|
|
||||||
var planet = pseudoRandom.pick(planets, arr);
|
|
||||||
planet.station = planet.generateStation(pseudoRandom);
|
|
||||||
planet.station.seed = planet.seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Star;
|
|
107
twister.js
107
twister.js
|
@ -1,107 +0,0 @@
|
||||||
var MersenneTwister = function(seed) {
|
|
||||||
if (seed == undefined) {
|
|
||||||
seed = new Date().getTime();
|
|
||||||
}
|
|
||||||
this.N = 624;
|
|
||||||
this.M = 397;
|
|
||||||
this.MATRIX_A = 0x9908b0df;
|
|
||||||
this.UPPER_MASK = 0x80000000;
|
|
||||||
this.LOWER_MASK = 0x7fffffff;
|
|
||||||
this.mt = new Array(this.N);
|
|
||||||
this.mti = this.N + 1;
|
|
||||||
this.init_genrand(seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.init_genrand = function(s) {
|
|
||||||
this.mt[0] = s >>> 0;
|
|
||||||
for (this.mti = 1; this.mti < this.N; this.mti++) {
|
|
||||||
var s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30);
|
|
||||||
this.mt[this.mti] = (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) +
|
|
||||||
this.mti;
|
|
||||||
this.mt[this.mti] >>>= 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.init_by_array = function(init_key, key_length) {
|
|
||||||
var i, j, k;
|
|
||||||
this.init_genrand(19650218);
|
|
||||||
i = 1;
|
|
||||||
j = 0;
|
|
||||||
k = (this.N > key_length ? this.N : key_length);
|
|
||||||
for (; k; k--) {
|
|
||||||
var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30)
|
|
||||||
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) +
|
|
||||||
init_key[j] + j;
|
|
||||||
this.mt[i] >>>= 0;
|
|
||||||
i++;
|
|
||||||
j++;
|
|
||||||
if (i >= this.N) {
|
|
||||||
this.mt[0] = this.mt[this.N - 1];
|
|
||||||
i = 1;
|
|
||||||
}
|
|
||||||
if (j >= key_length) j = 0;
|
|
||||||
}
|
|
||||||
for (k = this.N - 1; k; k--) {
|
|
||||||
var s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
|
|
||||||
this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) -
|
|
||||||
i;
|
|
||||||
this.mt[i] >>>= 0;
|
|
||||||
i++;
|
|
||||||
if (i >= this.N) {
|
|
||||||
this.mt[0] = this.mt[this.N - 1];
|
|
||||||
i = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.mt[0] = 0x80000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.genrand_int32 = function() {
|
|
||||||
var y;
|
|
||||||
var mag01 = new Array(0x0, this.MATRIX_A);
|
|
||||||
if (this.mti >= this.N) {
|
|
||||||
var kk;
|
|
||||||
if (this.mti == this.N + 1)
|
|
||||||
this.init_genrand(5489);
|
|
||||||
for (kk = 0; kk < this.N - this.M; kk++) {
|
|
||||||
y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK);
|
|
||||||
this.mt[kk] = this.mt[kk + this.M] ^ (y >>> 1) ^ mag01[y & 0x1];
|
|
||||||
}
|
|
||||||
for (; kk < this.N - 1; kk++) {
|
|
||||||
y = (this.mt[kk] & this.UPPER_MASK) | (this.mt[kk + 1] & this.LOWER_MASK);
|
|
||||||
this.mt[kk] = this.mt[kk + (this.M - this.N)] ^ (y >>> 1) ^ mag01[y & 0x1];
|
|
||||||
}
|
|
||||||
y = (this.mt[this.N - 1] & this.UPPER_MASK) | (this.mt[0] & this.LOWER_MASK);
|
|
||||||
this.mt[this.N - 1] = this.mt[this.M - 1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
|
||||||
this.mti = 0;
|
|
||||||
}
|
|
||||||
y = this.mt[this.mti++];
|
|
||||||
y ^= (y >>> 11);
|
|
||||||
y ^= (y << 7) & 0x9d2c5680;
|
|
||||||
y ^= (y << 15) & 0xefc60000;
|
|
||||||
y ^= (y >>> 18);
|
|
||||||
return y >>> 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.genrand_int31 = function() {
|
|
||||||
return (this.genrand_int32() >>> 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.genrand_real1 = function() {
|
|
||||||
return this.genrand_int32() * (1.0 / 4294967295.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.random = function() {
|
|
||||||
return this.genrand_int32() * (1.0 / 4294967296.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.genrand_real3 = function() {
|
|
||||||
return (this.genrand_int32() + 0.5) * (1.0 / 4294967296.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MersenneTwister.prototype.genrand_res53 = function() {
|
|
||||||
var a = this.genrand_int32() >>> 5,
|
|
||||||
b = this.genrand_int32() >>> 6;
|
|
||||||
return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = MersenneTwister;
|
|
98
utils.js
98
utils.js
|
@ -1,71 +1,6 @@
|
||||||
const PRNG = require('./prng');
|
Math.clamp = function(a, min, max) {
|
||||||
const data = require('./data.json');
|
return a < min ? min : (a > max ? max : a);
|
||||||
|
};
|
||||||
function random_name(PRNG, number_of_syllables, allow_second_name, allow_secondary) {
|
|
||||||
var syllables = [], name;
|
|
||||||
syllables.push(PRNG.pick(data.nameParts.prefix));
|
|
||||||
for (var j = 2; j < number_of_syllables; j++) {
|
|
||||||
syllables.push(PRNG.pick(data.nameParts.middle));
|
|
||||||
}
|
|
||||||
syllables.push(PRNG.pick(data.nameParts.suffix));
|
|
||||||
name = syllables.join('');
|
|
||||||
suffix = PRNG.pick(['', 'first-name', 'second-name', 'secondary'], [8, 1, 1, 4]);
|
|
||||||
switch (suffix) {
|
|
||||||
case 'first-name':
|
|
||||||
if (allow_second_name !== false) {
|
|
||||||
name = random_name(PRNG, PRNG.range(2, number_of_syllables), false, false) + " " + name;
|
|
||||||
name = kappatalize(name);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'second-name':
|
|
||||||
if (allow_second_name !== false) {
|
|
||||||
name = name + " " + random_name(PRNG, PRNG.range(2, number_of_syllables), false);
|
|
||||||
name = kappatalize(name);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'secondary':
|
|
||||||
if (allow_secondary !== false) {
|
|
||||||
name += " " + PRNG.pick(data.nameParts.secondary);
|
|
||||||
name = kappatalize(name);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return kappatalize(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function gravity(radius, density) {
|
|
||||||
return density / 5.56 * radius / 6557;
|
|
||||||
}
|
|
||||||
|
|
||||||
function blackbody(insolation, albedo) {
|
|
||||||
if (albedo === undefined) {
|
|
||||||
albedo = 0;
|
|
||||||
}
|
|
||||||
return Math.pow((1367 * insolation * (1 - albedo)) / (4 * 0.0000000567), 0.25);
|
|
||||||
}
|
|
||||||
|
|
||||||
function fixed_value(val) {
|
|
||||||
return function() {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function romanNumeral(n) {
|
|
||||||
var units = ["I", "I", "I", "IV", "V", "VI", "VI", "VI", "IX"];
|
|
||||||
if (n == 0) {
|
|
||||||
return "";
|
|
||||||
} else if (n < 0 || n >= 20) {
|
|
||||||
return n;
|
|
||||||
} else if (n >= 10) {
|
|
||||||
return "X" + romanNumeral(n - 10);
|
|
||||||
} else {
|
|
||||||
return units[n - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function kappatalize(str) {
|
|
||||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Array.prototype.indexContains = function(word) {
|
Array.prototype.indexContains = function(word) {
|
||||||
for (var idx = 0; idx < this.length; idx++) {
|
for (var idx = 0; idx < this.length; idx++) {
|
||||||
|
@ -75,29 +10,12 @@ Array.prototype.indexContains = function(word) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
Math.clamp = function(a, min, max) {
|
|
||||||
return a < min ? min : (a > max ? max : a);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Array.prototype.insertAt = function(where, what) {
|
String.prototype.capitalize = function() {
|
||||||
if (where < 0) {
|
if (this) {
|
||||||
this.splice(0, 0, what);
|
return this.substr(0, 1).toUpperCase() + this.substr(1);
|
||||||
} else {
|
} else {
|
||||||
var tail = this.splice(where);
|
return '';
|
||||||
this.push(what)
|
|
||||||
for (var i = 0; i < tail.length; i++) {
|
|
||||||
this.push(tail[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
"random_name": random_name,
|
|
||||||
"gravity": gravity,
|
|
||||||
"blackbody": blackbody,
|
|
||||||
"fixed_value": fixed_value,
|
|
||||||
"romanNumeral": romanNumeral,
|
|
||||||
"kappatalize": kappatalize
|
|
||||||
}
|
|
||||||
|
|
Reference in a new issue