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