Galactic Bloodshed
makestar.cc
Go to the documentation of this file.
1 // Copyright 2014 The Galactic Bloodshed Authors. All rights reserved.
2 // Use of this source code is governed by a license that can be
3 // found in the COPYING file.
4 
5 /* makestar.c -- create, name, position, and make planets for a star. */
6 
7 // G.O.D. [1] > methane melts at -182C
8 // G.O.D. [1] > it boils at -164
9 // G.O.D. [1] > ammonia melts at -78C
10 // G.O.D. [1] > boils at -33
11 
12 #include "gb/creator/makestar.h"
13 
14 #include <cmath>
15 #include <cstdio>
16 #include <cstdlib>
17 #include <cstring>
18 
19 #include "gb/creator/makeplanet.h"
20 #include "gb/creator/makeuniv.h"
21 #include "gb/files.h"
22 #include "gb/files_shl.h"
23 #include "gb/tweakables.h"
24 #include "gb/utils/rand.h"
25 #include "gb/vars.h"
26 
27 static const double PLANET_DIST_MAX = 1900.0;
28 static const double PLANET_DIST_MIN = 100.0;
29 
30 #ifndef M_PI
31 #define M_PI 3.14159265358979323846
32 #endif
33 
34 static char *NextStarName();
35 static const char *NextPlanetName(int);
36 
37 static int Numtypes[PlanetType::DESERT + 2] = {
38  0,
39 };
40 static int Resource[PlanetType::DESERT + 2] = {
41  0,
42 };
43 static int Numsects[PlanetType::DESERT + 2][SectorType::SEC_PLATED + 1] = {
44  {
45  0,
46  },
47 };
48 static int Fertsects[PlanetType::DESERT + 2][SectorType::SEC_PLATED + 1] = {
49  {
50  0,
51  },
52 };
53 static int numplist, namepcount;
54 static char PNames[1000][20];
55 static int planet_list[1000];
56 static int numslist, namestcount;
57 static char SNames[1000][20];
58 static int star_list[1000];
59 
60 static int ReadNameList(char ss[1000][20], int n, int m, const char *filename);
61 static void rand_list(int n, int *list);
62 
63 // TODO(jeffbailey): This should be syncd with the ones in GB_server.h:
64 static const char *Nametypes[] = {"Earth", "Asteroid", "Airless",
65  "Iceball", "Gaseous", "Water",
66  "Forest", "Desert", " >>"};
67 
68 int Temperature(double dist, int stemp) {
69  return -269 + stemp * 1315 * 40 / (40 + dist);
70 }
71 
73  int i;
74  int j;
75  int y;
76 
77  printf("\nPlanet/Sector distribution -\n");
78  printf(
79  "Type NP . * ^ ~ # ( - NS Avg Res "
80  "Avg A/Sec\n");
81  for (i = 0; i <= PlanetType::DESERT + 1; i++) {
82  printf("%3.3s%4d ", Nametypes[i], Numtypes[i]);
83  if (i < PlanetType::DESERT + 1)
84  Numtypes[PlanetType::DESERT + 1] += Numtypes[i];
85  for (j = 0; j < SectorType::SEC_PLATED; j++) {
86  printf("%5d", Numsects[i][j]);
87  Numsects[i][SectorType::SEC_PLATED] += Numsects[i][j];
88  if (i <= PlanetType::DESERT)
89  Numsects[PlanetType::DESERT + 1][j] += Numsects[i][j];
90  }
91  printf("%6d %5.1f", Numsects[i][SectorType::SEC_PLATED],
92  (1.0 * Numsects[i][SectorType::SEC_PLATED]) / Numtypes[i]);
93  printf("%8d %7.1f %5.1f\n", Resource[i],
94  ((double)Resource[i]) / Numtypes[i],
95  ((double)Resource[i]) / Numsects[i][SectorType::SEC_PLATED]);
96  Resource[PlanetType::DESERT + 1] += Resource[i];
97  }
98  printf("Average Sector Fertility -\n");
99  printf("Type NP . * ^ ~ # ( - Fert /Plan /Sect\n");
100  for (i = 0; i <= PlanetType::DESERT + 1; i++) {
101  printf("%3.3s%4d ", Nametypes[i], Numtypes[i]);
102  y = 0;
103  for (j = 0; j < SectorType::SEC_PLATED; j++) {
104  if (Numsects[i][j])
105  printf("%5.1f", ((double)Fertsects[i][j]) / Numsects[i][j]);
106  else
107  printf(" -");
108  y += Fertsects[i][j];
109  Fertsects[PlanetType::DESERT + 1][j] += Fertsects[i][j];
110  }
111  printf("%8d %7.1f %5.1f\n", y, (1.0 * y) / Numtypes[i],
112  (1.0 * y) / Numsects[i][SectorType::SEC_PLATED]);
113  }
114 }
115 
116 static int ReadNameList(char ss[1000][20], int n, int m, const char *filename) {
117  int i;
118  int j;
119  FILE *f = fopen(filename, "r");
120 
121  if (f == nullptr) {
122  printf("Unable to open \"%s\".\n", filename);
123  return -1;
124  }
125  for (i = 0; i < n; i++) {
126  for (j = 0; j < m; j++)
127  if ('\n' == (ss[i][j] = getc(f))) {
128  ss[i][j] = '\0';
129  goto next;
130  } else if (EOF == ss[i][j])
131  goto out;
132  ss[i][j - 1] = '\0';
133  while ('\n' != (j = getc(f)))
134  if (EOF == j) goto out;
135  next:;
136  }
137 out:
138  fclose(f);
139  printf("%d names listed in %s\n", i, filename);
140  return i;
141 }
142 
143 static void rand_list(int n, int *list) /* mix up the numbers 0 thru n */
144 {
145  short nums[1000];
146  short i;
147  short j;
148  short k;
149  short kk;
150  short ii;
151 
152  for (i = 0; i <= n; i++) nums[i] = 0;
153  for (j = 0; j <= n; j++) {
154  i = k = int_rand(0, n);
155  while (nums[k] != 0) k += nums[k];
156  list[j] = k;
157  if (k == n) {
158  nums[k] = -n;
159  kk = 0;
160  } else {
161  nums[k] = 1;
162  kk = k + 1;
163  }
164  /* K is now the next position in the list after the most recent number. */
165  /* Go through the list, making each pointer point to k. */
166  while (i != k) {
167  ii = i + nums[i];
168  nums[i] = kk - i;
169  i = ii;
170  }
171  }
172 }
173 
175  numplist = ReadNameList(PNames, 1000, 20, PLANETLIST);
177  if (numplist < 0) exit(0);
178  namepcount = 0;
179 }
180 
181 static const char *NextPlanetName(int i) {
182  const char *Numbers[] = {"1", "2", "3", "4", "5", "6", "7", "8",
183  "9", "10", "11", "12", "13", "14", "15"};
184  if (autoname_plan && (namepcount < numplist))
185  return PNames[planet_list[namepcount++]];
186 
187  return Numbers[i];
188 }
189 
191  numslist = ReadNameList(SNames, 1000, 20, STARLIST);
193  if (numslist < 0) exit(0);
194  namestcount = 0;
195 }
196 
197 static char *NextStarName() {
198  static char buf[20];
199  int i;
200 
201  if (autoname_star && (namestcount <= numslist))
202  return SNames[star_list[namestcount++]];
203 
204  printf("Next star name:");
205  for (i = 0; i < NAMESIZE - 4; i++) putchr('.');
206  for (i = 0; i < NAMESIZE - 4; i++) putchr('\010'); /* ^H */
207  scanf("%14[^\n]", buf);
208  getchr();
209 
210  return buf;
211 }
212 
213 startype *Makestar(int snum) {
214  PlanetType type;
215  int roll;
216  int temperature;
217  int i;
218  int y;
219  int x;
220  double dist;
221  double distmin;
222  double distmax;
223  double distsep;
224  double angle;
225  double xpos;
226  double ypos;
227  startype *Star;
228 
229  /* get names, positions of stars first */
230  Star = (startype *)malloc(sizeof(startype));
231  bzero(Star, sizeof(startype));
232  Star->star_id = snum;
233  Star->gravity = int_rand(0, int_rand(0, 300)) + int_rand(0, 300) +
234  int_rand(100, 400) + int_rand(0, 9) / 10.0;
235  Star->temperature = round_rand(Star->gravity / 100.0);
236  /* + int_rand(0,2) - 1 ; */
237  strcpy(Star->name, NextStarName());
238  place_star(Star);
239  if (printstarinfo)
240  printf("Star %s: gravity %1.1f, temp %d\n", Star->name, Star->gravity,
241  (int)Star->temperature);
242  /*
243  * Generate planets for this star: */
244  Star->numplanets = int_rand(minplanets, maxplanets);
245 
246  distmin = PLANET_DIST_MIN;
247  for (i = 0; i < Star->numplanets; i++) {
248  distsep = (PLANET_DIST_MAX - distmin) / (double)(Star->numplanets - i);
249  distmax = distmin + distsep;
250  dist = distmin + double_rand() * (distmax - distmin);
251  distmin = dist;
252 
253  temperature = Temperature(dist, Star->temperature);
254  angle = 2.0 * M_PI * double_rand();
255  xpos = dist * sin(angle);
256  ypos = dist * cos(angle);
257 
258  strcpy(Star->pnames[i], NextPlanetName(i));
259 
260  roll = int_rand(1, 100);
261  if ((int_rand(1, 100) <= 10) || (temperature > 400)) {
262  type = PlanetType::ASTEROID;
263  } else if ((temperature > 100) && (temperature <= 400)) {
264  if (roll <= 60)
265  type = PlanetType::MARS;
266  else
267  type = PlanetType::DESERT;
268  } else if ((temperature > 30) && (temperature <= 100)) {
269  if (roll <= 25)
270  type = PlanetType::EARTH;
271  else if (roll <= 50)
272  type = PlanetType::WATER;
273  else if (roll <= 80)
274  type = PlanetType::FOREST;
275  else if (roll <= 90)
276  type = PlanetType::DESERT;
277  else
278  type = PlanetType::MARS;
279  } else if ((temperature > -10) && (temperature <= 30)) {
280  if (roll <= 45)
281  type = PlanetType::EARTH;
282  else if (roll <= 70)
283  type = PlanetType::WATER;
284  else if (roll <= 95)
285  type = PlanetType::FOREST;
286  else
287  type = PlanetType::DESERT;
288  } else if ((temperature > -50) && (temperature <= -10)) {
289  if (roll <= 30)
290  type = PlanetType::DESERT;
291  else if (roll <= 60)
292  type = PlanetType::ICEBALL;
293  else if (roll <= 90)
294  type = PlanetType::FOREST;
295  else
296  type = PlanetType::MARS;
297  } else if ((temperature > -100) && (temperature <= -50)) {
298  if (roll <= 50)
299  type = PlanetType::GASGIANT;
300  else if (roll <= 80)
301  type = PlanetType::ICEBALL;
302  else
303  type = PlanetType::MARS;
304  } else if (temperature <= -100) {
305  if (roll <= 80)
306  type = PlanetType::ICEBALL;
307  else
308  type = PlanetType::GASGIANT;
309  }
310  auto planet = Makeplanet(dist, Star->temperature, type);
311  auto smap = getsmap(planet);
312  planet.xpos = xpos;
313  planet.ypos = ypos;
314  planet.total_resources = 0;
315  Numtypes[type]++;
316  if (printplaninfo) {
317  printf("Planet %s: temp %d, type %s (%u)\n", Star->pnames[i],
318  planet.conditions[RTEMP], Nametypes[planet.type], planet.type);
319  printf("Position is (%1.0f,%1.0f) relative to %s; distance %1.0f.\n",
320  planet.xpos, planet.ypos, Star->name, dist);
321  printf("sect map(%dx%d):\n", planet.Maxx, planet.Maxy);
322  for (y = 0; y < planet.Maxy; y++) {
323  for (x = 0; x < planet.Maxx; x++) {
324  switch (smap.get(x, y).condition) {
325  case SectorType::SEC_LAND:
326  putchr(CHAR_LAND);
327  break;
328  case SectorType::SEC_SEA:
329  putchr(CHAR_SEA);
330  break;
331  case SectorType::SEC_MOUNT:
332  putchr(CHAR_MOUNT);
333  break;
334  case SectorType::SEC_ICE:
335  putchr(CHAR_ICE);
336  break;
337  case SectorType::SEC_GAS:
338  putchr(CHAR_GAS);
339  break;
340  case SectorType::SEC_DESERT:
341  putchr(CHAR_DESERT);
342  break;
343  case SectorType::SEC_FOREST:
344  putchr(CHAR_FOREST);
345  break;
346  default:
347  putchr('?');
348  break;
349  }
350  }
351  putchr('\n');
352  }
353  putchr('\n');
354  }
355  /*
356  * Tabulate statistics for this star's planets. */
357  for (y = 0; y < planet.Maxy; y++)
358  for (x = 0; x < planet.Maxx; x++) {
359  uint8_t d = smap.get(x, y).condition;
360  planet.total_resources += smap.get(x, y).resource;
361  Resource[type] += smap.get(x, y).resource;
362  Numsects[type][d]++;
363  Fertsects[type][d] += smap.get(x, y).fert;
364  }
365  Star->planetpos[i] = 0; // old posn of file-last write
366  putplanet(planet, Star, i);
367  }
368  return Star;
369 }
#define STARLIST
Definition: files.h:48
int autoname_plan
Definition: makeuniv.cc:32
static int star_list[1000]
Definition: makestar.cc:58
int maxplanets
Definition: makeuniv.cc:34
static const char * Nametypes[]
Definition: makestar.cc:64
static int Fertsects[PlanetType::DESERT+2][SectorType::SEC_PLATED+1]
Definition: makestar.cc:48
Planet Makeplanet(double, short, PlanetType)
Definition: makeplanet.cc:86
static char * NextStarName()
Definition: makestar.cc:197
#define M_PI
Definition: makestar.cc:31
static char SNames[1000][20]
Definition: makestar.cc:57
#define getchr()
Definition: tweakables.h:210
int printstarinfo
Definition: makeuniv.cc:36
#define putchr(c)
Definition: tweakables.h:211
static int Numtypes[PlanetType::DESERT+2]
Definition: makestar.cc:37
static const double PLANET_DIST_MIN
Definition: makestar.cc:28
static int numplist
Definition: makestar.cc:53
static int planet_list[1000]
Definition: makestar.cc:55
#define PLANETLIST
Definition: files.h:47
startype * Makestar(int)
Definition: makestar.cc:213
void Makestar_init()
Definition: makestar.cc:190
static int ReadNameList(char ss[1000][20], int n, int m, const char *filename)
Definition: makestar.cc:116
static int Numsects[PlanetType::DESERT+2][SectorType::SEC_PLATED+1]
Definition: makestar.cc:43
int autoname_star
Definition: makeuniv.cc:31
void PrintStatistics()
Definition: makestar.cc:72
static int Resource[PlanetType::DESERT+2]
Definition: makestar.cc:40
void place_star(startype *)
Definition: makeuniv.cc:228
int Temperature(double dist, int stemp)
Definition: makestar.cc:68
int printplaninfo
Definition: makeuniv.cc:35
void putplanet(const Planet &p, startype *star, const int pnum)
Definition: files_shl.cc:934
SectorMap getsmap(const Planet &p)
Definition: files_shl.cc:522
#define RTEMP
Definition: tweakables.h:29
int minplanets
Definition: makeuniv.cc:33
#define NAMESIZE
Definition: tweakables.h:66
static int namepcount
Definition: makestar.cc:53
static int numslist
Definition: makestar.cc:56
static void rand_list(int n, int *list)
Definition: makestar.cc:143
static const char * NextPlanetName(int)
Definition: makestar.cc:181
static const double PLANET_DIST_MAX
Definition: makestar.cc:27
static char PNames[1000][20]
Definition: makestar.cc:54
static int namestcount
Definition: makestar.cc:56
void Makeplanet_init()
Definition: makestar.cc:174