7 #include "gb/creator/makeplanet.h" 16 #include "gb/creator/makestar.h" 17 #include "gb/files_shl.h" 18 #include "gb/tweakables.h" 19 #include "gb/utils/rand.h" 23 static const int xmin[] = {15, 2, 4, 4, 26, 12, 12, 12};
24 static const int xmax[] = {23, 4, 8, 8, 32, 20, 20, 20};
32 static const int x_chance[] = {5, 15, 10, 4, 5, 7, 6};
33 static const int Fmin[][8] = {{25, 20, 10, 0, 20, 45, 5},
34 {0, 1, 2, 0, 0, 0, 1},
35 {0, 3, 2, 0, 0, 0, 2},
36 {0, 0, 8, 0, 25, 0, 0},
37 {0, 0, 0, 35, 0, 0, 0},
38 {30, 0, 0, 0, 20, 0, 0},
39 {30, 25, 20, 0, 30, 60, 15},
40 {0, 5, 2, 0, 0, 0, 2}};
43 static const int Fmax[][8] = {{40, 35, 20, 0, 40, 65, 15},
44 {0, 2, 3, 0, 0, 0, 2},
45 {0, 5, 4, 0, 0, 0, 3},
46 {0, 0, 15, 0, 35, 0, 0},
47 {0, 0, 0, 55, 0, 0, 0},
48 {50, 0, 0, 0, 40, 0, 0},
49 {60, 45, 30, 0, 50, 90, 25},
50 {0, 10, 6, 0, 0, 0, 8}};
53 static const int rmin[][8] = {{200, 225, 300, 0, 200, 0, 250},
54 {0, 250, 350, 0, 0, 0, 300},
55 {0, 225, 275, 0, 0, 0, 250},
56 {0, 0, 250, 0, 225, 0, 0},
57 {0, 0, 0, 30, 0, 0, 0},
58 {175, 0, 0, 0, 200, 0, 0},
59 {150, 0, 0, 0, 150, 150, 0},
60 {0, 200, 300, 0, 0, 0, 250}};
63 static const int rmax[][8] = {{250, 325, 400, 0, 250, 0, 300},
64 {0, 300, 600, 0, 0, 0, 400},
65 {0, 300, 500, 0, 0, 0, 300},
66 {0, 0, 350, 0, 300, 0, 0},
67 {0, 0, 0, 60, 0, 0, 0},
68 {225, 0, 0, 0, 250, 0, 0},
69 {250, 0, 0, 0, 250, 200, 0},
70 {0, 200, 500, 0, 0, 0, 350}};
74 static const int cond[] = {SectorType::SEC_SEA, SectorType::SEC_MOUNT,
75 SectorType::SEC_LAND, SectorType::SEC_ICE,
76 SectorType::SEC_GAS, SectorType::SEC_SEA,
77 SectorType::SEC_FOREST, SectorType::SEC_DESERT};
79 static int neighbors(SectorMap &,
int,
int,
int);
81 static void Makesurface(
const Planet &, SectorMap &);
82 static int SectTemp(
const Planet &,
const int);
83 static void seed(SectorMap &,
int,
int);
84 static void grow(SectorMap &,
int,
int,
int);
86 Planet
Makeplanet(
double dist,
short stemp, PlanetType type) {
87 static planetnum_t planet_id = 0;
97 bzero(&planet,
sizeof(planet));
98 planet.planet_id = planet_id;
101 planet.expltimer = 5;
104 planet.Maxx = int_rand(
xmin[type],
xmax[type]);
105 f = (
double)planet.Maxx /
RATIOXY;
106 planet.Maxy = round_rand(f) + 1;
107 if (!(planet.Maxy % 2)) planet.Maxy++;
109 if (type == PlanetType::ASTEROID)
110 planet.Maxy = int_rand(1, 3);
115 SectorMap smap(planet,
true);
116 for (y = 0; y < planet.Maxy; y++) {
117 for (x = 0; x < planet.Maxx; x++) {
118 auto &s = smap.get(x, y);
119 s.type = s.condition = t;
123 total_sects = (planet.Maxy - 1) * (planet.Maxx - 1);
126 case PlanetType::GASGIANT:
128 if (int_rand(0, 1)) {
129 atmos = 100 - (planet.conditions[
METHANE] = int_rand(70, 80));
130 atmos -= planet.conditions[
HYDROGEN] = int_rand(1, atmos / 2);
131 atmos -= planet.conditions[
HELIUM] = 1;
132 atmos -= planet.conditions[
OXYGEN] = 0;
133 atmos -= planet.conditions[
CO2] = 1;
134 atmos -= planet.conditions[
NITROGEN] = int_rand(1, atmos / 2);
135 atmos -= planet.conditions[
SULFUR] = 0;
136 planet.conditions[
OTHER] = atmos;
138 atmos = 100 - (planet.conditions[
HYDROGEN] = int_rand(30, 75));
139 atmos -= planet.conditions[
HELIUM] = int_rand(20, atmos / 2);
140 atmos -= planet.conditions[
METHANE] = random() & 01;
141 atmos -= planet.conditions[
OXYGEN] = 0;
142 atmos -= planet.conditions[
CO2] = random() & 01;
143 atmos -= planet.conditions[
NITROGEN] = int_rand(1, atmos / 2);
144 atmos -= planet.conditions[
SULFUR] = 0;
145 planet.conditions[
OTHER] = atmos;
148 case PlanetType::MARS:
150 planet.conditions[
HELIUM] = 0;
151 planet.conditions[
METHANE] = 0;
152 planet.conditions[
OXYGEN] = 0;
154 atmos = 100 - (planet.conditions[
CO2] = int_rand(30, 45));
155 atmos -= planet.conditions[
NITROGEN] = int_rand(10, atmos / 2);
156 atmos -= planet.conditions[
SULFUR] =
157 (random() & 01) ? 0 : int_rand(20, atmos / 2);
158 atmos -= planet.conditions[
OTHER] = atmos;
160 planet.conditions[
CO2] = 0;
162 planet.conditions[
SULFUR] = 0;
163 planet.conditions[
OTHER] = 0;
165 seed(smap
, SectorType::SEC_DESERT
, int_rand(1, total_sects)
);
166 seed(smap
, SectorType::SEC_MOUNT
, int_rand(1, total_sects)
);
168 case PlanetType::ASTEROID:
170 for (y = 0; y < planet.Maxy; y++)
171 for (x = 0; x < planet.Maxx; x++)
172 if (!int_rand(0, 3)) {
173 auto &s = smap.get_random();
174 s.type = s.condition = SectorType::SEC_LAND;
176 seed(smap
, DESERT
, int_rand(1, total_sects)
);
178 case PlanetType::ICEBALL:
181 planet.conditions[
HELIUM] = 0;
182 planet.conditions[
METHANE] = 0;
183 planet.conditions[
OXYGEN] = 0;
184 if (planet.Maxx * planet.Maxy > int_rand(0, 20)) {
185 atmos = 100 - (planet.conditions[
CO2] = int_rand(30, 45));
186 atmos -= planet.conditions[
NITROGEN] = int_rand(10, atmos / 2);
187 atmos -= planet.conditions[
SULFUR] =
188 (random() & 01) ? 0 : int_rand(20, atmos / 2);
189 atmos -= planet.conditions[
OTHER] = atmos;
191 planet.conditions[
CO2] = 0;
193 planet.conditions[
SULFUR] = 0;
194 planet.conditions[
OTHER] = 0;
196 seed(smap
, SectorType::SEC_MOUNT
, int_rand(1, total_sects / 2)
);
198 case PlanetType::EARTH:
200 seed(smap
, SectorType::SEC_LAND
, 201 int_rand(total_sects / 30, total_sects / 20)
);
207 case PlanetType::FOREST:
209 seed(smap
, SectorType::SEC_SEA
, 210 int_rand(total_sects / 30, total_sects / 20)
);
213 grow(smap
, SectorType::SEC_FOREST
, 1
, 3
);
215 case PlanetType::WATER:
218 case PlanetType::DESERT:
220 seed(smap
, SectorType::SEC_MOUNT
, 221 int_rand(total_sects / 50, total_sects / 25)
);
224 seed(smap
, SectorType::SEC_LAND
, 225 int_rand(total_sects / 50, total_sects / 25)
);
228 grow(smap
, SectorType::SEC_DESERT
, 1
, 3
);
237 static void MakeEarthAtmosphere(Planet &planet,
const int chance) {
240 if (int_rand(0, 99) > chance) {
242 atmos -= planet.conditions[
OXYGEN] = int_rand(10, 25);
243 atmos -= planet.conditions[
NITROGEN] = int_rand(20, atmos - 20);
244 atmos -= planet.conditions[
CO2] = int_rand(10, atmos / 2);
245 atmos -= planet.conditions[
HELIUM] = int_rand(2, atmos / 8 + 1);
246 atmos -= planet.conditions[
METHANE] = random() & 01;
247 atmos -= planet.conditions[
SULFUR] = 0;
248 atmos -= planet.conditions[
HYDROGEN] = 0;
249 planet.conditions[
OTHER] = atmos;
252 atmos -= planet.conditions[
METHANE] = int_rand(70, 80);
253 atmos -= planet.conditions[
HYDROGEN] = int_rand(1, atmos / 2);
254 atmos -= planet.conditions[
HELIUM] = 1 + (random() & 01);
255 atmos -= planet.conditions[
OXYGEN] = 0;
256 atmos -= planet.conditions[
CO2] = 1 + (random() & 01);
257 atmos -= planet.conditions[
SULFUR] = (random() & 01);
258 atmos -= planet.conditions[
NITROGEN] = int_rand(1, atmos / 2);
259 planet.conditions[
OTHER] = atmos;
264 static int neighbors(SectorMap &smap,
int x,
int y,
int type) {
270 l = smap.get_maxx() - 1;
271 else if (r == smap.get_maxx())
274 n += (smap.get(x, y - 1).type == type) + (smap.get(l, y - 1).type == type) +
275 (smap.get(r, y - 1).type == type);
277 n += (smap.get(l, y).type == type) + (smap.get(r, y).type == type);
279 if (y < smap.get_maxy() - 1)
280 n += (smap.get(x, y + 1).type == type) + (smap.get(l, y + 1).type == type) +
281 (smap.get(r, y + 1).type == type);
287 static void seed(SectorMap &smap,
int type,
int n) {
289 auto &s = smap.get_random();
290 s.type = s.condition = type;
298 static void grow(SectorMap &smap,
int type,
int n,
int rate) {
299 std::vector<std::tuple<
int,
int,
int>> worklist;
305 for (
int x = 0; x < smap.get_maxx(); x++) {
306 for (
int y = 0; y < smap.get_maxy(); y++) {
308 worklist.emplace_back(std::make_tuple(x, y, type));
314 for (
auto &[x, y, sector_type] : worklist) {
315 auto &s = smap.get(x, y);
316 s.condition = s.type = sector_type;
321 for (
int x = 0; x < smap.get_maxx(); x++) {
322 for (
int y = 0; y < smap.get_maxy(); y++) {
323 auto &s = smap.get(x, y);
326 case SectorType::SEC_SEA:
327 if (success(-temp) && ((y == 0) || (y == smap.get_maxy() - 1)))
328 s.condition = SectorType::SEC_ICE;
330 case SectorType::SEC_LAND:
331 if (p.type == PlanetType::EARTH) {
332 if (success(-temp) && (y == 0 || y == smap.get_maxy() - 1))
333 s.condition = SectorType::SEC_ICE;
336 case SectorType::SEC_FOREST:
337 if (p.type == PlanetType::FOREST) {
338 if (success(-temp) && (y == 0 || y == smap.get_maxy() - 1))
339 s.condition = SectorType::SEC_ICE;
342 s.type = s.condition;
343 s.resource = int_rand(
rmin[p.type][s.type],
rmax[p.type][s.type]);
344 s.fert = int_rand(
Fmin[p.type][s.type],
Fmax[p.type][s.type]);
345 if (int_rand(0, 1000) <
x_chance[s.type])
346 s.crystals = int_rand(4, 8);
356 int temp = p.conditions[
TEMP];
357 int mid = (p.Maxy + 1) / 2 - 1;
358 int dy = abs(y - mid);
360 temp -= TFAC * dy * dy;
static void Makesurface(const Planet &, SectorMap &)
Planet Makeplanet(double, short, PlanetType)
static void MakeEarthAtmosphere(Planet &, int)
static const int Fmax[][8]
static const int rmax[][8]
static const int rmin[][8]
void putsmap(SectorMap &map, Planet &p)
static int SectTemp(const Planet &, const int)
static int neighbors(SectorMap &, int, int, int)
Returns # of neighbors of a given designation that a sector has.
static void grow(SectorMap &, int, int, int)
int Temperature(double dist, int stemp)
static void seed(SectorMap &, int, int)
Randomly places n sectors of designation type on a planet.
static const int x_chance[]
static const int Fmin[][8]