-
-
Save beautyfree/2268b53530d82584d8f0b83aed7b8304 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { planetHexasphere } from '../client/hexasphere.js'; | |
import PlanetGenerator from '../client/planet-generator.js'; | |
import '../hybrid/helpers.js'; | |
import { prettyUrl } from '../../../deps.js'; | |
import { getHexagonalGeometry } from '../hybrid/coordinates.js'; | |
class Generator { | |
constructor() { | |
return new Promise(async resolve => { | |
this.systemTypes = await mongoDb.collection('systemTypes').find().toArray(); | |
this.planetTypes = await mongoDb.collection('planetTypes').find().toArray(); | |
this.systemPossibilities = this.generateSystemPossibilities(); | |
this.planetPossibilities = this.generatePlanetPossibilities(); | |
//l(this); | |
resolve(this); | |
}); | |
} | |
rand(min, max) { | |
return Math.round(Math.random() * (max - min) + min); | |
} | |
generateSystemPossibilities() { | |
const probabilities = []; | |
const systemTypes = {}; | |
for (const systemType of this.systemTypes) { | |
for (let i = 0; i < systemType.probability; i++) { | |
probabilities.push(systemType.name); | |
systemTypes[systemType.name] = systemType; | |
} | |
} | |
this.systemTypes = systemTypes; | |
return probabilities; | |
} | |
generatePlanetPossibilities() { | |
const probabilities = []; | |
const planetTypes = {}; | |
for (const planetType of this.planetTypes) { | |
for (let i = 0; i < planetType.probability; i++) { | |
probabilities.push(planetType.name); | |
planetTypes[planetType.name] = planetType; | |
} | |
} | |
this.planetTypes = planetTypes; | |
return probabilities; | |
} | |
async generate() { | |
await mongoDb.drop('users'); | |
await mongoDb.drop('nations'); | |
await mongoDb.drop('spaceTiles'); | |
await mongoDb.drop('planets'); | |
await mongoDb.drop('planetTiles'); | |
await mongoDb.drop('settlements'); | |
await mongoDb.collection('spaceTiles').createIndexes({ | |
indexes: [/*{ | |
name: 'uniqueXY', | |
key: { coordinates: }, | |
unique: 1, | |
}, */{ | |
name: 'geo2d', | |
key: { coordinates: '2d' }, | |
unique: 1, | |
min: -999999, | |
max: 999999, | |
}] | |
}); | |
// Miserit Anhtar System | |
const system = { | |
coordinates: [0, 0], | |
type: 'BLUE', | |
name: 'Miserit Anthar' | |
}; | |
system.url = prettyUrl(system.name); | |
const systemId = await mongoDb.collection('spaceTiles').insertOne(system); | |
let planet; | |
let distanceToSun = 10; | |
distanceToSun += this.rand(3, 5); | |
planet = { | |
index: 0, | |
systemId, | |
size: 4, //size | |
type: 'LAVA', //type | |
name: 'Lavara', //name | |
rotationSpeed: -0.015, //rotation speed positive is clockwise | |
distanceToSun, // distance from center of the sun, | |
orbitSpeed: 150, // orbit speed | |
//i: Date.now(), // last time position was at null degrees | |
}; | |
planet.url = prettyUrl(planet.name); | |
planet._id = await mongoDb.collection('planets').insertOne(planet); | |
this.generatePlanetTiles(planet); | |
distanceToSun += this.rand(3, 5); | |
planet = { | |
index: 1, | |
systemId, | |
size: 5, //size | |
type: 'DESERT', //type | |
name: 'Hasaroh', //name | |
rotationSpeed: -0.015, //rotation speed positive is clockwise | |
distanceToSun, // distance from center of the sun, | |
orbitSpeed: 100, // orbit speed | |
//i: Date.now(), // last time position was at null degrees | |
}; | |
planet.url = prettyUrl(planet.name); | |
planet._id = await mongoDb.collection('planets').insertOne(planet); | |
this.generatePlanetTiles(planet); | |
distanceToSun += this.rand(3, 5); | |
planet = { | |
index: 2, | |
systemId, | |
size: 7, | |
type: 'BARREN', | |
name: 'Roxan', | |
rotationSpeed: -0.015, //rotation speed positive is clockwise | |
distanceToSun, // distance from center of the sun, | |
orbitSpeed: 200, // orbit speed | |
//i: Date.now(), // last time position was at null degrees | |
}; | |
planet.url = prettyUrl(planet.name); | |
planet._id = await mongoDb.collection('planets').insertOne(planet); | |
this.generatePlanetTiles(planet); | |
distanceToSun += this.rand(3, 5); | |
planet = { | |
index: 3, | |
systemId, | |
size: 18, | |
type: 'EARTHLIKE', | |
name: 'Miserit', | |
rotationSpeed: -0.015, //rotation speed positive is clockwise | |
distanceToSun, // distance from center of the sun, | |
orbitSpeed: 300, // orbit speed | |
//i: Date.now(), // last time position was at null degrees | |
}; | |
planet.url = prettyUrl(planet.name); | |
planet._id = await mongoDb.collection('planets').insertOne(planet); | |
this.generatePlanetTiles(planet); | |
distanceToSun += this.rand(3, 5); | |
planet = { | |
index: 4, | |
systemId, | |
size: 20, | |
type: 'EARTHLIKE', | |
name: 'Anthar', | |
rotationSpeed: -0.015, //rotation speed positive is clockwise | |
distanceToSun, // distance from center of the sun, | |
orbitSpeed: 400, // orbit speed | |
//i: Date.now(), // last time position was at null degrees | |
}; | |
planet.url = prettyUrl(planet.name); | |
planet._id = await mongoDb.collection('planets').insertOne(planet); | |
this.generatePlanetTiles(planet); | |
distanceToSun += this.rand(3, 5); | |
planet = { | |
index: 5, | |
systemId, | |
size: 20, | |
type: 'GAS', | |
name: 'Gosa', | |
rotationSpeed: -0.015, //rotation speed positive is clockwise | |
distanceToSun, // distance from center of the sun, | |
orbitSpeed: 500, // orbit speed | |
//i: Date.now(), // last time position was at null degrees | |
}; | |
planet.url = prettyUrl(planet.name); | |
planet._id = await mongoDb.collection('planets').insertOne(planet); | |
this.generatePlanetTiles(planet); | |
const circleStart = 1; | |
const circleEnd = 20; | |
for (let circle = circleStart; circle <= circleEnd; circle++) { | |
const tilesInCurrentCircle = this.generateCircle(circle, 0, 0); | |
for (const tile of tilesInCurrentCircle) { | |
await this.generateTile(tile[0], tile[1]); | |
} | |
} | |
} | |
generateCircle(r, x = 0, y = 0) { | |
return tileRing(r, x, y); | |
} | |
async generateTile(x, y) { | |
let stop = false; | |
// step1: check if there is no other solar system in the surrounding tiles | |
const neighbors = [ | |
...this.generateCircle(1, x, y), // tile around | |
...this.generateCircle(2, x, y) // two tiles around | |
]; | |
//l('>>>neighbors', x, y, neighbors); | |
const tiles = await mongoDb.collection('spaceTiles').find({ coordinates: { $in: neighbors } }).toArray(); | |
//l('>>>neighbors', neighbors, tiles); | |
for (const neighbor of tiles) { | |
if (neighbor.type) { | |
stop = true; | |
break; | |
} | |
} | |
// step2: Decide randomly if current tile gets a solar system | |
if (!stop) { | |
const random = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]; | |
const r = this.rand(0, 10); | |
//l('>>>dice', r); | |
if (random[r]) { | |
await this.generateSolarSystem(x, y); | |
} else { | |
stop = true; | |
} | |
} | |
if (stop) { | |
await mongoDb.collection('spaceTiles').insertOne({ | |
coordinates: [x, y], | |
}); | |
//l(`created (${x}|${y})</b> space`); | |
} | |
} | |
async generateSolarSystem(x, y) { | |
const type = this.getRandomSystemType(); | |
const name = await this.generateName(); | |
const system = { | |
coordinates: [x, y], | |
type, | |
name | |
}; | |
system.url = prettyUrl(system.name); | |
const systemId = await mongoDb.collection('spaceTiles').insertOne(system); | |
l(`created (${x}|${y}) system ${name} of type ${type}`); | |
// Decide how many planets current solar system has | |
const planets = this.rand(0, this.systemTypes[type].planets); | |
let distanceToSun = 10; | |
// Decide what size and type those planets are | |
for (let i = 0; i < planets; i++) { | |
distanceToSun += this.rand(3, 5); | |
if (distanceToSun > 85) { | |
break; | |
} | |
let type = this.getRandomPlanetType(); | |
const size = this.rand(type.min_size, type.max_size); | |
const planetName = name + ' ' + (i + 1); | |
const planet = { | |
index: i, | |
systemId, | |
size, | |
type: type.name, | |
name: planetName, | |
distanceToSun, | |
orbitSpeed: this.rand(50, 950), | |
rotationSpeed: this.rand(.01, .05), | |
}; | |
planet.url = prettyUrl(planet.name); | |
// has rings | |
if (this.rand(0, 9) > 4) { | |
planet.rings = { | |
radius: this.rand(-Math.PI, Math.PI), | |
width: this.rand(2, 20) | |
}; | |
} | |
planet._id = await mongoDb.collection('planets').insertOne(planet); | |
this.generatePlanetTiles(planet); | |
} | |
} | |
async generatePlanetTiles(planet) { | |
const tiles = []; | |
const hexasphere = planetHexasphere(planet); | |
const pg = new PlanetGenerator(hexasphere, planet); | |
for (const index in pg.hexasphere.tiles) { | |
const tile = pg.hexasphere.tiles[index]; | |
const n = tile.neighbors.map(n => n.index); | |
const newTile = { | |
planetId: planet._id, | |
index: Number(index), // index | |
type: tile.t, // type | |
height: tile.h, // height | |
forest: tile.f, // forest | |
resources: tile.resources, | |
neighbors: n, // neighbors | |
center: { | |
x: tile.centerPoint.x, | |
y: tile.centerPoint.y, | |
z: tile.centerPoint.z, | |
}, | |
} | |
tiles.push(newTile); | |
} | |
await mongoDb.collection('planetTiles').insertMany(tiles); | |
} | |
getRandomSystemType() { | |
return this.systemPossibilities[this.rand(0, this.systemPossibilities.length - 1)]; | |
} | |
async generateName() { | |
let name = []; | |
const vocals = ['a', 'e', 'i', 'o', 'u']; | |
const consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z']; | |
const words = this.rand(1, 3); | |
for (let w = 0; w < words; w++) { | |
let word = ''; | |
const letters = this.rand(3, 5); | |
for (let l = 0; l < letters; l++) { | |
if (l % 2) { | |
word += vocals[this.rand(0, 4)]; | |
} else { | |
word += consonants[this.rand(0, 20)]; | |
} | |
} | |
name.push(word); | |
} | |
for (const key in name) { | |
name[key] = name[key][0].toUpperCase() + name[key].slice(1); | |
} | |
name = name.join(' ', name); | |
const check1 = await mongoDb.collection('tiles').find({ name }).toArray(); | |
const check2 = await mongoDb.collection('planets').find({ name }).toArray(); | |
if (check1.length === 0 && check2.length === 0) { | |
return name; | |
} else { | |
return this.generateName(); | |
} | |
} | |
getRandomPlanetType() { | |
return this.planetTypes[this.planetPossibilities[this.rand(0, this.planetPossibilities.length - 1)]]; | |
} | |
} | |
self.Generator = Generator; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment