comparison src/pl_gen5.c @ 4:aa38447a4b21

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:03 +0000
parents
children
comparison
equal deleted inserted replaced
3:cafa94d86546 4:aa38447a4b21
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.75) /* 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 }
273 } while (!done && attempts < 200); /* do until location found */
274
275 if (!done)
276 return 0; /* universe too crowded, try again */
277
278 move_planet(n, (int) x, (int) y, 0);
279 planets[n].pl_system = i + 1; /* mark the sytem number */
280 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY);
281 n++; /* go to next planet */
282 }
283 }
284 return (n); /* return index of next planet */
285 }
286
287
288
289
290 /*-----------------------------PLACEINDEP------------------------------*/
291 /*
292 * This function places idependent planets that are not in a system. They can
293 * appear anywhere in the galaxy as long as they are not too close to another
294 * planet. The coords are put in the space grid.
295 */
296
297 static int
298 placeindep(n)
299 int n;
300 /* number of planet to start with */
301 {
302 int i, j; /* looping vars */
303 double x, y; /* to hold star coordinates */
304 int done; /* flag to indicate done */
305 double dx, dy; /* delta x and y's */
306 int attempts;
307
308 for (i = n; i < (NUMPLANETS - (WORMPAIRS * 2)); i++)
309 {
310 /* go through rest of planets */
311 x = drand48() * (GW - 2 * INDBORD) + INDBORD; /* pick intial coords */
312 y = drand48() * (GW - 2 * INDBORD) + INDBORD;
313 attempts = 0;
314 do
315 { /* do until location found */
316 attempts++;
317 done = 0; /* not done yet */
318 x = INDBORD + fmod(x + (3574.0 - INDBORD), GW - 2 * INDBORD); /* offset coords a
319 * little */
320 y = INDBORD + fmod(y + (1034.0 - INDBORD), GW - 2 * INDBORD); /* every loop */
321 #if 0
322 if ((x > GW - INDBORD) || (x < INDBORD)
323 || (y < INDBORD) || (y > GW - INDBORD))
324 continue; /* too close to border? */
325 #endif
326 done = 1; /* assume valid coord */
327 for (j = 0; j < n; j++)
328 { /* go through previous planets */
329 dx = fabs(x - (double) planets[j].pl_x);
330 dy = fabs(y - (double) planets[j].pl_y);
331 if (dx * dx + dy * dy < SYSMIN2)
332 { /* if planet to close */
333 done = 0; /* we must get another coord */
334 }
335 }
336 } while (!done && attempts < 200); /* do until location found */
337
338 if (!done)
339 return 0;
340
341 move_planet(n, (int) x, (int) y, 0);
342 planets[n].pl_system = 0; /* mark the no sytem */
343 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY);
344 n++; /* go to next planet */
345 }
346 for (i = n; i < NUMPLANETS; i++) /* now place wormholes */
347 {
348 x = drand48() * GW; /* pick intial coords */
349 y = drand48() * GW;
350 attempts = 0;
351 do
352 { /* do until location found */
353 attempts++;
354 done = 0; /* not done yet */
355 x = fmod(x + 3574.0, GW); /* offset coords a little */
356 y = fmod(y + 1034.0, GW); /* every loop */
357 #if 0
358 if ((x > GW) || (y > GW))
359 continue; /* too close to border? */
360 #endif
361 done = 1; /* assume valid coord */
362 for (j = 0; j < n; j++)
363 { /* go through previous planets */
364 dx = fabs(x - (double) planets[j].pl_x);
365 dy = fabs(y - (double) planets[j].pl_y);
366 if (dx * dx + dy * dy < SYSMIN2)
367 { /* if planet to close */
368 done = 0; /* we must get another coord */
369 }
370 }
371 } while (!done && attempts < 200); /* do until location found */
372
373 if (!done)
374 return 0;
375
376 move_planet(n, (int) x, (int) y, 0);
377 planets[n].pl_system = 0; /* mark the no system */
378 planets[n].pl_flags |= PLWHOLE; /* mark the planet as a wormhole */
379 /* the armies in a wormhole is the other wormhole's x coord */
380 /* the radius is the other wormhole's y coord */
381 if (NUMPLANETS % 2)
382 {
383 if (!(n % 2))
384 {
385 planets[n].pl_armies = planets[n - 1].pl_x;
386 planets[n].pl_radius = planets[n - 1].pl_y;
387 planets[n - 1].pl_armies = planets[n].pl_x;
388 planets[n - 1].pl_radius = planets[n].pl_y;
389 }
390 }
391 else
392 {
393 if (n % 2)
394 {
395 planets[n].pl_armies = planets[n - 1].pl_x;
396 planets[n].pl_radius = planets[n - 1].pl_y;
397 planets[n - 1].pl_armies = planets[n].pl_x;
398 planets[n - 1].pl_radius = planets[n].pl_y;
399 }
400 }
401 planets[i].pl_owner = NOBODY; /* no team owns a star */
402 planets[i].pl_hinfo = ALLTEAM; /* all teams know its a star */
403 for (j = 0; j < MAXTEAM + 1; j++)
404 { /* go put in info for teams */
405 planets[i].pl_tinfo[j].owner = NOBODY; /* nobody owns it */
406 planets[i].pl_tinfo[j].armies = 0;
407 planets[i].pl_tinfo[j].flags = planets[i].pl_flags;
408 }
409 n++; /* go to next planet */
410 }
411 return 1;
412 }
413
414
415
416
417 /*---------------------------------PLACERACES------------------------------*/
418 /*
419 * This function places the races in the galaxy. Each race is placed in a
420 * different system. The race is given a home world with an Agri and Ship-
421 * yard on it and HOMEARMIES. They are also given a conoly planet with
422 * dilythium deposits and COLONYARMIES on it.
423 */
424
425 static void
426 placeraces()
427 {
428 int i, j, k; /* looping vars */
429 int p; /* to hold planet for race */
430
431 for (i = 0; i < 4; i++)
432 { /* go through races */
433 /* find home planet */
434 p = lrand48() % NUMPLANETS; /* pick random planet */
435 while ((planets[p].pl_system != i + 1)
436 || (PL_TYPE(planets[p]) == PLSTAR)
437 || (planets[p].pl_owner != NOBODY))
438 p = (p + 1) % NUMPLANETS; /* go on to next planet */
439 planets[p].pl_flags &= ~PLSURMASK; /* make sure no dilithium */
440 planets[p].pl_flags |= (PLMETAL | PLARABLE); /* metal and arable */
441 planets[p].pl_flags |= PLATYPE1; /* good atmosphere */
442 planets[p].pl_flags |= (PLAGRI | PLSHIPYARD | PLREPAIR);
443 planets[p].pl_tagri = PLGAGRI; /* set timers for resources */
444 planets[p].pl_tshiprepair = PLGSHIP;
445 planets[p].pl_owner = 1 << i; /* make race the owner */
446 #if 0 /* home planets do not have traditional names */
447 strcpy(planets[p].pl_name, homenames[1 << i]); /* set name and length */
448 planets[p].pl_namelen = strlen(homenames[1 << i]);
449 #endif
450 planets[p].pl_armies = HOMEARMIES; /* set the armies */
451 planets[p].pl_hinfo = 1 << i; /* race has info on planet */
452 planets[p].pl_tinfo[1 << i].owner = 1 << i; /* know about owner */
453 planets[p].pl_tinfo[1 << i].armies = planets[p].pl_armies;
454 planets[p].pl_tinfo[1 << i].flags = planets[p].pl_flags;
455 /* find colony planet */
456 p = lrand48() % NUMPLANETS; /* pick random planet */
457 while ((planets[p].pl_system != i + 1)
458 || (PL_TYPE(planets[p]) == PLSTAR)
459 || (planets[p].pl_owner != NOBODY))
460 p = (p + 1) % NUMPLANETS; /* go on to next planet */
461 planets[p].pl_flags |= PLFUEL; /* make fuel depot */
462 planets[p].pl_tfuel = PLGFUEL; /* set timer for fuel depot */
463 planets[p].pl_flags &= ~PLATMASK; /* take off previous atmos */
464 planets[p].pl_flags |= PLPOISON; /* poison atmosphere */
465 planets[p].pl_flags |= PLDILYTH; /* dilythium deposits */
466 planets[p].pl_owner = 1 << i; /* make race the owner */
467 planets[p].pl_armies = COLONYARMIES; /* set the armies */
468 planets[p].pl_hinfo = 1 << i; /* race knows about */
469 planets[p].pl_tinfo[1 << i].owner = 1 << i; /* know about owner */
470 planets[p].pl_tinfo[1 << i].armies = planets[p].pl_armies;
471 planets[p].pl_tinfo[1 << i].flags = planets[p].pl_flags;
472 for (j = 0; j < NUMPLANETS; j++)
473 {
474 if ((planets[j].pl_system == i + 1) && (PL_TYPE(planets[j]) != PLSTAR))
475 {
476 #ifdef LEAGUE_SUPPORT
477 for (k = (status2->league ? 0 : i);
478 k < (status2->league ? 4 : i + 1);
479 k++)
480 #else
481 k = i;
482 #endif
483 {
484 planets[j].pl_owner = 1 << i;
485 planets[j].pl_hinfo =
486 #ifdef LEAGUE_SUPPORT
487 status2->league ? (1 << 4) - 1 :
488 #endif
489 (1 << i);
490 planets[j].pl_tinfo[1 << k].owner = 1 << i;
491 planets[j].pl_tinfo[1 << k].armies = planets[j].pl_armies;
492 planets[j].pl_tinfo[1 << k].flags = planets[j].pl_flags;
493 }
494 }
495 }
496 }
497 }
498
499 /*
500 * Generate a complete galaxy. Generates like generator 3, only in a smaller
501 * environment
502 */
503
504 void
505 gen_galaxy_5()
506 {
507 int t;
508
509 GWIDTH = 100000;
510 NUMPLANETS = 48;
511
512 while (1)
513 {
514 initplanets(); /* initialize planet structures */
515
516 /* place the resources */
517 zero_plflags(planets, NUMPLANETS);
518 randomize_atmospheres(planets + SYSTEMS, NUMPLANETS - SYSTEMS,
519 PATMOS1, PATMOS2, PATMOS3, PPOISON);
520 randomize_resources(planets + SYSTEMS, NUMPLANETS - SYSTEMS,
521 NMETAL, NDILYTH, NARABLE);
522
523 /* place system centers */
524 t = place_stars(planets, 4,
525 (int) TEAMBORD, (int) TEAMMIN, (int) TEAMMAX,
526 (struct planet *) 0, 0)
527 && place_stars(planets + 4, SYSTEMS - 4,
528 (int) STARBORD, (int) STARMIN, (int) STARMAX,
529 planets, 4);
530
531 if (!t)
532 continue;
533 t = placesystems(); /* place planets in systems */
534 if (!t)
535 continue;
536 t = placeindep(t); /* place independent planets */
537 if (t)
538 break; /* success */
539 }
540 if (configvals->justify_galaxy)
541 justify_galaxy(SYSTEMS);
542 placeraces(); /* place home planets for races */
543
544 }