comparison src/pl_gen7.c @ 6:8c6d5731234d

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:04 +0000
parents
children
comparison
equal deleted inserted replaced
5:054275999194 6:8c6d5731234d
1 /*--------------------------------------------------------------------------
2 NETREK II -- Paradise
3
4 Permission to use, copy, modify, and distribute this software and its
5 documentation, or any derivative works thereof, for any NON-COMMERCIAL
6 purpose and without fee is hereby granted, provided that this copyright
7 notice appear in all copies. No representations are made about the
8 suitability of this software for any purpose. This software is provided
9 "as is" without express or implied warranty.
10
11 Xtrek Copyright 1986 Chris Guthrie
12 Netrek (Xtrek II) Copyright 1989 Kevin P. Smith
13 Scott Silvey
14 Paradise II (Netrek II) Copyright 1993 Larry Denys
15 Kurt Olsen
16 Brandon Gillespie
17 --------------------------------------------------------------------------*/
18 #include "config.h"
19 #include <math.h>
20
21 #include "defs.h"
22 #include "struct.h"
23 #include "data.h"
24 #include "shmem.h"
25 #include "planets.h"
26
27 #define SYSWIDTH (GWIDTH/5.9) /* width of a system */
28
29 #define SYSTEMS 7 /* number of planetary systems */
30
31 /* atmosphere chances form a cascade win rand()%100 */
32 #define PATMOS1 40 /* chance for normal atmosphere */
33 #define PATMOS2 70 /* chance for thin atmosphere */
34 #define PATMOS3 90 /* chance for slightly toxic stmos */
35 #define PPOISON 100 /* chance for poison atmos */
36
37 /* defines that deal with planets resources and types */
38 #define NMETAL 10 /* number of metal deposits */
39 #define NDILYTH 8 /* number of dilythium deposits */
40 #define NARABLE 12 /* number of arable land planets */
41 /* defines that deal with star placement */
42
43 #define GW ((float)GWIDTH) /* size of galaxy in floating point */
44 #define STARBORD ((GW/5.2)*1.3)
45 #define TEAMBORD ((GW/5.2)/1.1)
46 #define STARMIN (GW/5.0)/* min dist between stars */
47 #define STARMIN2 (STARMIN*STARMIN) /* min star dist squared */
48 #define STARMAX GW
49 #define STARMAX2 (GW*GW)
50 #define TEAMMIN (GW/2.8)/* min dist between team stars */
51 #define TEAMMIN2 (TEAMMIN*TEAMMIN)
52 #define TEAMMAX (GW/1.4)/* max dist between team stars */
53 #define TEAMMAX2 (TEAMMAX*TEAMMAX)
54
55 /* defines that deal with systems and their planets */
56 #define SYSADD 2 /* number possible above min number */
57 #define SYSBORD (4000.0 + (float)GWIDTH/200) /* min distance from
58 * border wall */
59 #define INDBORD (GW * 0.1)
60 #define SYSMIN (6000.0 + (float)GWIDTH/200) /* min distance between
61 * objects */
62 #define SYSMIN2 (SYSMIN*SYSMIN) /* square of sysmin distance */
63 #define SYSPLMIN 5 /* min number of planets for system */
64 #define SYSPLADD 0 /* number of possible extra planets */
65 #define MINARMY 8 /* min numer of armies on a planet */
66 #define MAXARMY 15 /* max number of armies on a planet */
67
68 /* other defines */
69 #define HOMEARMIES 30 /* number of armies on home planets */
70 #define COLONYARMIES 10 /* number of armies for colony planet */
71
72
73 /* defines dealing with growth timers */
74 #define PLGFUEL configvals->plgrow.fuel /* time for growth of fuel
75 * depot */
76 #define PLGAGRI configvals->plgrow.agri /* time for growth of agri */
77 #define PLGREPAIR configvals->plgrow.repair /* time for growth of
78 * repair */
79 #define PLGSHIP configvals->plgrow.shipyard /* time for growth of
80 * shipyard */
81
82
83 #if 0
84 /*-------------------------------GENRESOURCES----------------------------*/
85 /*
86 * This function goes through the planets structure and determines what kind
87 * of atmosphere and what kind of surface the planets have. It generates the
88 * stars that will be used as system centers ans then places atmospheres on
89 * the other planets. It then distributes the resources on the planet
90 * surfaces.
91 */
92
93 static void
94 genresources()
95 {
96 int i; /* looping vars */
97 int t; /* temp var */
98
99 for (i = 0; i < SYSTEMS; i++) /* first planets are stars */
100 planets[i].pl_flags |= PLSTAR; /* or in star flag */
101 for (i = SYSTEMS; i < NUMPLANETS; i++)
102 { /* generate atmospheres */
103 t = lrand48() % 100; /* random # 0-99 */
104 if (t < PATMOS1) /* is it atmosphere type 1 */
105 planets[i].pl_flags |= PLATYPE1;
106 else if (t < PATMOS2) /* is it atmosphere type 2 */
107 planets[i].pl_flags |= PLATYPE2;
108 else if (t < PATMOS3) /* is it atmosphere type 3 */
109 planets[i].pl_flags |= PLATYPE3;
110 else if (t < PPOISON) /* is it poison atmosphere */
111 planets[i].pl_flags |= PLPOISON;
112 }
113 for (i = 0; i < NMETAL; i++)
114 { /* place the metal deposits */
115 t = lrand48() % (NUMPLANETS - SYSTEMS) + SYSTEMS; /* random planet */
116 planets[t].pl_flags |= PLMETAL; /* OR in the metal flag */
117 if (!configvals->resource_bombing)
118 planets[t].pl_flags |= PLREPAIR;
119 }
120 for (i = 0; i < NDILYTH; i++)
121 { /* place the metal deposits */
122 t = lrand48() % (NUMPLANETS - SYSTEMS) + SYSTEMS; /* random planet */
123 planets[t].pl_flags |= PLDILYTH; /* OR in the dilyth flag */
124 planets[t].pl_flags &= ~(PLATMASK | PLARABLE); /* zero off previous
125 * atmos */
126 planets[t].pl_flags |= PLPOISON; /* dilyth poisons atmosphere */
127 if (!configvals->resource_bombing)
128 planets[t].pl_flags |= PLFUEL;
129 }
130 for (i = 0; i < NARABLE; i++)
131 { /* place the metal deposits */
132 t = lrand48() % (NUMPLANETS - SYSTEMS) + SYSTEMS; /* random planet */
133 planets[t].pl_flags |= PLARABLE | PLATYPE1; /* OR in the arable flag */
134 if (!configvals->resource_bombing)
135 planets[t].pl_flags |= PLAGRI;
136 }
137 }
138 #endif
139
140
141 #if 0
142
143 /*--------------------------------PLACESTARS------------------------------*/
144 /*
145 * This function places each system's star. The stars are expected to be in
146 * the first SYSTEMS number of planets. The coordinates of the stars are
147 * placed in the space grid.
148 */
149
150 static int
151 placestars()
152 {
153 int i, j; /* looping vars */
154 double x, y; /* to hold star coordinates */
155 int done; /* flag to indicate done */
156 double dx, dy; /* delta x and y's */
157 int attempts;
158 double min, max, dist, bord, nbwidth;
159 double xoff, yoff;
160
161 for (i = 0; i < SYSTEMS; i++)
162 { /* star for each system */
163 if (i < 4)
164 {
165 min = TEAMMIN2;
166 max = TEAMMAX2;
167 bord = TEAMBORD;
168 }
169 else
170 {
171 min = STARMIN2;
172 max = STARMAX2;
173 bord = STARBORD;
174 }
175 nbwidth = GW - 2 * bord;
176 x = drand48() * nbwidth + bord; /* pick intial coords */
177 y = drand48() * nbwidth + bord;
178 xoff = 3574.0 - bord;
179 yoff = 1034.0 - bord;
180 attempts = 0;
181 do
182 { /* do until location found */
183 attempts++;
184 done = 0; /* not done yet */
185 x = bord + fmod(x + xoff, nbwidth); /* offset coords a little */
186 y = bord + fmod(y + yoff, nbwidth); /* every loop */
187 #if 0
188 if ((x > GW - bord) || (x < bord)
189 || (y < bord) || (y > GW - bord))
190 continue; /* too close to border? */
191 #endif
192 done = 1; /* assume valid cord found */
193 for (j = 0; j < i; j++)
194 { /* go through previous stars */
195 dx = fabs(x - (double) planets[j].pl_x);
196 dy = fabs(y - (double) planets[j].pl_y);
197 dist = dx * dx + dy * dy;
198 if (dist < min || dist > max) /* if too close or too far then */
199 done = 0; /* we must get another coord */
200 }
201 } while (!done && attempts < 1000); /* do until location found */
202
203 if (!done)
204 return 0;
205
206 planets[i].pl_owner = NOBODY; /* no team owns a star */
207 planets[i].pl_flags |= PLSTAR; /* mark planet as a star */
208 move_planet(i, (int) x, (int) y, 0);
209 planets[i].pl_system = i + 1; /* mark the sytem number */
210 planets[i].pl_hinfo = ALLTEAM; /* all teams know its a star */
211 for (j = 0; j < MAXTEAM + 1; j++)
212 { /* go put in info for teams */
213 planets[i].pl_tinfo[j].owner = NOBODY; /* nobody owns it */
214 planets[i].pl_tinfo[j].armies = 0;
215 planets[i].pl_tinfo[j].flags = planets[i].pl_flags;
216 }
217 }
218 return 1;
219 }
220
221 #endif
222
223
224 /*-----------------------------PLACESYSTEMS------------------------------*/
225 /*
226 * This function places the planets in each star's system. The function will
227 * return the index of the first planet that was not placed in a system. The
228 * coordinates of the planets are placed in the space grid.
229 */
230
231 static int
232 placesystems()
233 {
234 int i, j, k; /* looping vars */
235 double x, y; /* to hold star coordinates */
236 int done; /* flag to indicate done */
237 double dx, dy; /* delta x and y's */
238 int n; /* number of planet to place */
239 int np; /* number of planets in system */
240 int attempts;
241
242 n = SYSTEMS; /* first planet to place */
243 for (i = 0; i < SYSTEMS; i++)
244 { /* planets for each system */
245 np = SYSPLMIN + lrand48() % (SYSPLADD + 1); /* how many planets */
246 for (k = 0; k < np; k++)
247 { /* go place the planets */
248 attempts = 0;
249 do
250 { /* do until location found */
251 attempts++;
252 done = 0; /* not done yet */
253 dx = (drand48() * SYSWIDTH - SYSWIDTH / 2.0);
254 dy = (drand48() * SYSWIDTH - SYSWIDTH / 2.0);
255 if (dx * dx + dy * dy > (SYSWIDTH / 2.0) * (SYSWIDTH / 2.0))
256 continue; /* might orbit its way out of the galaxy */
257 x = planets[i].pl_x + dx;
258 y = planets[i].pl_y + dy;
259 if ((x > GW - SYSBORD) || (x < SYSBORD)
260 || (y < SYSBORD) || (y > GW - SYSBORD))
261 continue; /* too close to border? */
262
263 done = 1; /* assume valid coord found */
264 for (j = 0; j < n; j++)
265 { /* go through previous planets */
266 dx = fabs(x - (double) planets[j].pl_x);
267 dy = fabs(y - (double) planets[j].pl_y);
268 if (dx * dx + dy * dy < SYSMIN2)
269 { /* if too close to another star */
270 done = 0; /* we must get another coord */
271 }
272 if (ihypot((int) dx, (int) dy) < 3000)
273 done = 0;
274 }
275 } while (!done && attempts < 200); /* do until location found */
276
277 if (!done)
278 return 0; /* universe too crowded, try again */
279
280 move_planet(n, (int) x, (int) y, 0);
281 planets[n].pl_system = i + 1; /* mark the sytem number */
282 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY);
283 n++; /* go to next planet */
284 }
285 }
286 return (n); /* return index of next planet */
287 }
288
289
290
291
292 /*-----------------------------PLACEINDEP------------------------------*/
293 /*
294 * This function places idependent planets that are not in a system. They can
295 * appear anywhere in the galaxy as long as they are not too close to another
296 * planet. The coords are put in the space grid.
297 */
298
299 static int
300 placeindep(n)
301 int n;
302 /* number of planet to start with */
303 {
304 int i, j; /* looping vars */
305 double x, y; /* to hold star coordinates */
306 int done; /* flag to indicate done */
307 double dx, dy; /* delta x and y's */
308 int attempts;
309
310 for (i = n; i < (NUMPLANETS - (WORMPAIRS * 2)); i++)
311 {
312 /* go through rest of planets */
313 x = drand48() * (GW - 2 * INDBORD) + INDBORD; /* pick intial coords */
314 y = drand48() * (GW - 2 * INDBORD) + INDBORD;
315 attempts = 0;
316 do
317 { /* do until location found */
318 attempts++;
319 done = 0; /* not done yet */
320 x = INDBORD + fmod(x + (3574.0 - INDBORD), GW - 2 * INDBORD); /* offset coords a
321 * little */
322 y = INDBORD + fmod(y + (1034.0 - INDBORD), GW - 2 * INDBORD); /* every loop */
323 #if 0
324 if ((x > GW - INDBORD) || (x < INDBORD)
325 || (y < INDBORD) || (y > GW - INDBORD))
326 continue; /* too close to border? */
327 #endif
328 done = 1; /* assume valid coord */
329 for (j = 0; j < n; j++)
330 { /* go through previous planets */
331 dx = fabs(x - (double) planets[j].pl_x);
332 dy = fabs(y - (double) planets[j].pl_y);
333 if (dx * dx + dy * dy < SYSMIN2)
334 { /* if planet to close */
335 done = 0; /* we must get another coord */
336 }
337 }
338 } while (!done && attempts < 200); /* do until location found */
339
340 if (!done)
341 return 0;
342
343 move_planet(n, (int) x, (int) y, 0);
344 planets[n].pl_system = 0; /* mark the no sytem */
345 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY);
346 n++; /* go to next planet */
347 }
348 for (i = n; i < NUMPLANETS; i++) /* now place wormholes */
349 {
350 x = drand48() * GW; /* pick intial coords */
351 y = drand48() * GW;
352 attempts = 0;
353 do
354 { /* do until location found */
355 attempts++;
356 done = 0; /* not done yet */
357 x = fmod(x + 3574.0, GW); /* offset coords a little */
358 y = fmod(y + 1034.0, GW); /* every loop */
359 #if 0
360 if ((x > GW) || (y > GW))
361 continue; /* too close to border? */
362 #endif
363 done = 1; /* assume valid coord */
364 for (j = 0; j < n; j++)
365 { /* go through previous planets */
366 dx = fabs(x - (double) planets[j].pl_x);
367 dy = fabs(y - (double) planets[j].pl_y);
368 if (dx * dx + dy * dy < SYSMIN2)
369 { /* if planet to close */
370 done = 0; /* we must get another coord */
371 }
372 }
373 } while (!done && attempts < 200); /* do until location found */
374
375 if (!done)
376 return 0;
377
378 move_planet(n, (int) x, (int) y, 0);
379 planets[n].pl_system = 0; /* mark the no system */
380 planets[n].pl_flags |= PLWHOLE; /* mark the planet as a wormhole */
381 /* the armies in a wormhole is the other wormhole's x coord */
382 /* the radius is the other wormhole's y coord */
383 if (NUMPLANETS % 2)
384 {
385 if (!(n % 2))
386 {
387 planets[n].pl_armies = planets[n - 1].pl_x;
388 planets[n].pl_radius = planets[n - 1].pl_y;
389 planets[n - 1].pl_armies = planets[n].pl_x;
390 planets[n - 1].pl_radius = planets[n].pl_y;
391 }
392 }
393 else
394 {
395 if (n % 2)
396 {
397 planets[n].pl_armies = planets[n - 1].pl_x;
398 planets[n].pl_radius = planets[n - 1].pl_y;
399 planets[n - 1].pl_armies = planets[n].pl_x;
400 planets[n - 1].pl_radius = planets[n].pl_y;
401 }
402 }
403 planets[i].pl_owner = NOBODY; /* no team owns a star */
404 planets[i].pl_hinfo = ALLTEAM; /* all teams know its a star */
405 for (j = 0; j < MAXTEAM + 1; j++)
406 { /* go put in info for teams */
407 planets[i].pl_tinfo[j].owner = NOBODY; /* nobody owns it */
408 planets[i].pl_tinfo[j].armies = 0;
409 planets[i].pl_tinfo[j].flags = planets[i].pl_flags;
410 }
411 n++; /* go to next planet */
412 }
413 return 1;
414 }
415
416
417
418
419 /*---------------------------------PLACERACES------------------------------*/
420 /*
421 * This function places the races in the galaxy. Each race is placed in a
422 * different system. The race is given a home world with an Agri and Ship-
423 * yard on it and HOMEARMIES. They are also given a conoly planet with
424 * dilythium deposits and COLONYARMIES on it.
425 */
426
427 static void
428 placeraces()
429 {
430 int i, j, k; /* looping vars */
431 int p; /* to hold planet for race */
432
433 for (i = 0; i < 4; i++)
434 { /* go through races */
435 /* find home planet */
436 p = lrand48() % NUMPLANETS; /* pick random planet */
437 while ((planets[p].pl_system != i + 1)
438 || (PL_TYPE(planets[p]) == PLSTAR)
439 || (planets[p].pl_owner != NOBODY))
440 p = (p + 1) % NUMPLANETS; /* go on to next planet */
441 planets[p].pl_flags &= ~PLSURMASK; /* make sure no dilithium */
442 planets[p].pl_flags |= (PLMETAL | PLARABLE); /* metal and arable */
443 planets[p].pl_flags |= PLATYPE1; /* good atmosphere */
444 planets[p].pl_flags |= (PLAGRI | PLSHIPYARD | PLREPAIR);
445 planets[p].pl_tagri = PLGAGRI; /* set timers for resources */
446 planets[p].pl_tshiprepair = PLGSHIP;
447 planets[p].pl_owner = 1 << i; /* make race the owner */
448 #if 0 /* home planets do not have traditional names */
449 strcpy(planets[p].pl_name, homenames[1 << i]); /* set name and length */
450 planets[p].pl_namelen = strlen(homenames[1 << i]);
451 #endif
452 planets[p].pl_armies = HOMEARMIES; /* set the armies */
453 planets[p].pl_hinfo = 1 << i; /* race has info on planet */
454 planets[p].pl_tinfo[1 << i].owner = 1 << i; /* know about owner */
455 planets[p].pl_tinfo[1 << i].armies = planets[p].pl_armies;
456 planets[p].pl_tinfo[1 << i].flags = planets[p].pl_flags;
457 /* find colony planet */
458 p = lrand48() % NUMPLANETS; /* pick random planet */
459 while ((planets[p].pl_system != i + 1)
460 || (PL_TYPE(planets[p]) == PLSTAR)
461 || (planets[p].pl_owner != NOBODY))
462 p = (p + 1) % NUMPLANETS; /* go on to next planet */
463 planets[p].pl_flags |= PLFUEL; /* make fuel depot */
464 planets[p].pl_tfuel = PLGFUEL; /* set timer for fuel depot */
465 planets[p].pl_flags &= ~PLATMASK; /* take off previous atmos */
466 planets[p].pl_flags |= PLPOISON; /* poison atmosphere */
467 planets[p].pl_flags |= PLDILYTH; /* dilythium deposits */
468 planets[p].pl_owner = 1 << i; /* make race the owner */
469 planets[p].pl_armies = COLONYARMIES; /* set the armies */
470 planets[p].pl_hinfo = 1 << i; /* race knows about */
471 planets[p].pl_tinfo[1 << i].owner = 1 << i; /* know about owner */
472 planets[p].pl_tinfo[1 << i].armies = planets[p].pl_armies;
473 planets[p].pl_tinfo[1 << i].flags = planets[p].pl_flags;
474 for (j = 0; j < NUMPLANETS; j++)
475 {
476 if ((planets[j].pl_system == i + 1) && (PL_TYPE(planets[j]) != PLSTAR))
477 {
478 #ifdef LEAGUE_SUPPORT
479 for (k = (status2->league ? 0 : i);
480 k < (status2->league ? 4 : i + 1);
481 k++)
482 #else
483 k = i;
484 #endif
485 {
486 planets[j].pl_owner = 1 << i;
487 planets[j].pl_hinfo =
488 #ifdef LEAGUE_SUPPORT
489 status2->league ? (1 << 4) - 1 :
490 #endif
491 (1 << i);
492 planets[j].pl_tinfo[1 << k].owner = 1 << i;
493 planets[j].pl_tinfo[1 << k].armies = planets[j].pl_armies;
494 planets[j].pl_tinfo[1 << k].flags = planets[j].pl_flags;
495 }
496 }
497 }
498 }
499 }
500
501 /*
502 * Generate a complete galaxy, deepspace style. We use a 125k^2 grid with
503 * lots of planets for lots of fun. We're assuming a no-warp environment.
504 */
505
506 void
507 gen_galaxy_7()
508 {
509 int t;
510
511 GWIDTH = 125000;
512 NUMPLANETS = 60 - WORMPAIRS * 2;
513 configvals->warpdrive = 0;
514
515 while (1)
516 {
517 initplanets(); /* initialize planet structures */
518
519 /* place the resources */
520 zero_plflags(planets, NUMPLANETS);
521 randomize_atmospheres(planets + SYSTEMS, NUMPLANETS - SYSTEMS,
522 PATMOS1, PATMOS2, PATMOS3, PPOISON);
523 randomize_resources(planets + SYSTEMS, NUMPLANETS - SYSTEMS,
524 NMETAL, NDILYTH, NARABLE);
525
526 /* place system centers */
527 t = place_stars(planets, 4,
528 (int) TEAMBORD, (int) TEAMMIN, (int) TEAMMAX,
529 (struct planet *) 0, 0)
530 && place_stars(planets + 4, SYSTEMS - 4,
531 (int) STARBORD, (int) STARMIN, (int) STARMAX,
532 planets, 4);
533
534 if (!t)
535 continue;
536 t = placesystems(); /* place planets in systems */
537 if (!t)
538 continue;
539 t = placeindep(t); /* place independent planets */
540 if (t)
541 break; /* success */
542 }
543 if (configvals->justify_galaxy)
544 justify_galaxy(SYSTEMS);
545 placeraces(); /* place home planets for races */
546
547 }