Open source Star Ruler 2 source code!

This commit is contained in:
Lucas de Vries
2018-07-17 14:15:37 +02:00
commit cc307720ff
4342 changed files with 2365070 additions and 0 deletions
+276
View File
@@ -0,0 +1,276 @@
#include "include/map.as"
enum MapSetting {
M_SystemCount,
M_SystemSpacing,
M_Flatten,
};
#section server
class Room {
vec3d position;
uint circle = 0;
SystemData@ core;
array<SystemData@> systems;
array<uint> circles;
array<Room@> corrids;
};
#section all
class ClustersMap : Map {
ClustersMap() {
super();
name = locale::CLUSTERS_MAP;
description = locale::CLUSTERS_MAP_DESC;
sortIndex = -100;
color = 0xd8ff00ff;
icon = "maps/Clusters/clusters.png";
}
#section client
void makeSettings() {
Number(locale::SYSTEM_COUNT, M_SystemCount, DEFAULT_SYSTEM_COUNT, decimals=0, step=10, min=20, halfWidth=true);
Number(locale::SYSTEM_SPACING, M_SystemSpacing, DEFAULT_SPACING, decimals=0, step=1000, min=MIN_SPACING, halfWidth=true);
Toggle(locale::FLATTEN, M_Flatten, false, halfWidth=true);
}
#section server
void placeSystems() {
uint systemCount = uint(getSetting(M_SystemCount, DEFAULT_SYSTEM_COUNT));
double spacing = modSpacing(getSetting(M_SystemSpacing, DEFAULT_SPACING));
bool flatten = getSetting(M_Flatten, 0.0) != 0.0;
//Calculate amount of 'rooms'
uint roomCnt = max(ceil(pow(double(systemCount), 0.33)), double(max(estPlayerCount+1, 4)));
uint corridorLength = clamp(ceil(double(systemCount) / 50.0), 1, 5);
uint sysPerRoom = max(double(systemCount) / double(roomCnt) - double(corridorLength), 4.0);
if(sysPerRoom % 2 != 0)
sysPerRoom -= 1;
double roomRadius = spacing * 1.5 * sqrt(double(sysPerRoom)) + spacing;
double glxRadius = roomRadius * sqrt(double(roomCnt));
double roomHeightVar = flatten ? 0.0 : roomRadius * 0.2;
double sysHeightVar = flatten ? 0.0 : spacing * 0.25;
//Generate rooms
double angle = 0.0;
double radius = 0.0;
double angleStep = twopi;
double anglePct = 0.0;
double startAngle = randomd(0.0, twopi);
array<Room@> rooms;
Room@ circleStart;
uint circle = 0;
uint circleCnt = 0;
for(uint i = 0; i < roomCnt; ++i) {
Room room;
room.position = quaterniond_fromAxisAngle(vec3d_up(), angle + startAngle) * vec3d_front(radius);
room.position.y = randomd(-roomHeightVar, roomHeightVar);
room.circle = circle;
//Make room connections
if(rooms.length != 0 && (roomCnt-i+circleCnt) > 2) {
if(rooms[i-1].circle == circle)
room.corrids.insertLast(rooms[i-1]);
}
if(circleStart is null)
@circleStart = room;
rooms.insertLast(room);
++circleCnt;
//Generate links to previous circle
if(circle > 0) {
Room@ closest;
double closestDist = INFINITY;
Room@ second;
double secondDist = INFINITY;
for(int j = int(i); j >= 0; --j) {
if(rooms[j].circle < circle-1)
break;
if(rooms[j].circle > circle-1)
continue;
Room@ other = rooms[j];
double d = other.position.distanceToSQ(room.position);
if(d < closestDist) {
@second = closest;
secondDist = closestDist;
closestDist = d;
@closest = other;
}
else if(d < secondDist) {
@second = other;
secondDist = d;
}
}
if(closest !is null)
room.corrids.insertLast(closest);
if(second !is null)
room.corrids.insertLast(second);
}
//Proceed to next room position
angle += angleStep;
if(angle + angleStep > twopi) {
angle = 0.0;
radius += roomRadius;
startAngle = randomd(0.0, twopi);
anglePct = (roomRadius / (2.0 * pi * radius));
if(roomCnt - i - 1 > 0)
angleStep = max(anglePct * twopi, twopi / double(roomCnt - i - 1));
circle += 1;
if(circleStart !is null && circle != 1 && circleStart !is room && circleCnt > 2)
room.corrids.insertLast(circleStart);
@circleStart = null;
circleCnt = 0;
}
}
//Generate systems
for(uint i = 0; i < roomCnt; ++i) {
Room@ room = rooms[i];
//Generate systems
angle = 0.0;
radius = 0.0;
angleStep = twopi;
startAngle = randomd(0.0, twopi);
circle = 0;
int quality = 0;
if(i == 0 && roomCnt > estPlayerCount)
quality = 100;
uint hwInd = randomi(0, sysPerRoom-1);
for(uint n = 0; n < sysPerRoom; ++n) {
//Generate system
vec3d pos = quaterniond_fromAxisAngle(vec3d_up(), angle + startAngle) * vec3d_front(radius);
pos.y = randomd(-sysHeightVar, sysHeightVar);
pos += room.position;
SystemData@ sys = addSystem(pos, quality=quality);
if(i != 0) {
if(hwInd == n)
addPossibleHomeworld(sys);
}
else if(circle == 0) {
auto@ blackHole = getSystemType("CoreBlackhole");
if(blackHole !is null)
sys.systemType = int(blackHole.id);
}
room.systems.insertLast(sys);
room.circles.insertLast(circle);
//Generate links to previous circle
if(circle > 0) {
SystemData@ closest;
double closestDist = INFINITY;
SystemData@ second;
double secondDist = INFINITY;
for(int j = int(n); j >= 0; --j) {
if(room.circles[j] < circle-1)
break;
if(room.circles[j] > circle-1)
continue;
SystemData@ other = room.systems[j];
double d = other.position.distanceToSQ(sys.position);
if(d < closestDist) {
@second = closest;
secondDist = closestDist;
closestDist = d;
@closest = other;
}
else if(d < secondDist) {
@second = other;
secondDist = d;
}
}
if(closest !is null)
addLink(sys, closest);
if(second !is null)
addLink(sys, second);
}
//Proceed to next system position
angle += angleStep;
if(angle + angleStep > twopi) {
angle = 0.0;
radius += spacing;
startAngle = randomd(0.0, twopi);
anglePct = (spacing / (2.0 * pi * radius));
if(sysPerRoom - n - 1 > 0)
angleStep = max(anglePct * twopi, twopi / double(sysPerRoom - n - 1));
circle += 1;
}
}
}
//Generate corridors
for(uint i = 0; i < roomCnt; ++i) {
Room@ room = rooms[i];
for(uint n = 0, ncnt = room.corrids.length; n < ncnt; ++n) {
Room@ other = room.corrids[n];
//Build corridor between rooms
vec3d offset = (other.position - room.position);
double offdist = offset.length;
double spacStep = spacing / offdist;
double corStart = roomRadius * 0.5 / offdist;
double corEnd = 1.0 - corStart;
uint len = clamp(floor((corEnd - corStart) / spacStep), 1, corridorLength);
double corStep = (corEnd - corStart) / double(len);
corStart += corStep * 0.5;
SystemData@ first, last;
for(uint x = 0; x < len; ++x) {
vec3d corPos = room.position + offset * (corStep * x + corStart);
if(room.circle == other.circle)
corPos = corPos.normalized(room.position.length - roomRadius * 0.25);
auto@ sys = addSystem(corPos, quality=200);
if(last !is null)
addLink(last, sys);
@last = sys;
if(x == 0)
@first = last;
}
//Find systems to link to
double dist = INFINITY;
SystemData@ closest;
for(uint j = 0, jcnt = room.systems.length; j < jcnt; ++j) {
double d = room.systems[j].position.distanceToSQ(first.position);
if(d < dist) {
@closest = room.systems[j];
dist = d;
}
}
addLink(closest, first);
dist = INFINITY;
for(uint j = 0, jcnt = other.systems.length; j < jcnt; ++j) {
double d = other.systems[j].position.distanceToSQ(last.position);
if(d < dist) {
@closest = other.systems[j];
dist = d;
}
}
addLink(closest, last);
}
}
}
#section all
};