comparison src/pl_gen1.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) /* width of a system */
28
29 #define SYSTEMS 9 /* 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 2 /* number of metal deposits */
39 #define NDILYTH 10 /* number of dilythium deposits */
40 #define NARABLE 30 /* 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 (SYSWIDTH/2)
45 #define STARMIN (GW/3.7)/* min dist between stars */
46 #define STARMIN2 STARMIN*STARMIN /* min star dist squared */
47
48 /* defines that deal with systems and their planets */
49 #define SYSMINP 4 /* min number of planets per system */
50 #define SYSADD 2 /* number possible above min number */
51 #define SYSBORD (5000.0 + (float)(GWIDTH/200)) /* min distance from
52 * border wall */
53 #define SYSMIN (7000.0 + (float)(GWIDTH/100)) /* min distance between
54 * 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 < SYSTEMS; i++) /* first planets are stars */
93 planets[i].pl_flags |= PLSTAR; /* or in star flag */
94 for (i = SYSTEMS; i < NUMPLANETS; i++)
95 { /* generate atmospheres */
96 t = lrand48() % 100; /* random # 0-99 */
97 if (t < PATMOS1) /* is it atmosphere type 1 */
98 planets[i].pl_flags |= PLATYPE1;
99 else if (t < PATMOS2) /* is it atmosphere type 2 */
100 planets[i].pl_flags |= PLATYPE2;
101 else if (t < PATMOS3) /* is it atmosphere type 3 */
102 planets[i].pl_flags |= PLATYPE3;
103 else if (t < PPOISON) /* is it poison atmosphere */
104 planets[i].pl_flags |= PLPOISON;
105 }
106 for (i = 0; i < NMETAL; i++)
107 { /* place the metal deposits */
108 t = lrand48() % (NUMPLANETS - SYSTEMS) + SYSTEMS; /* random planet */
109 planets[t].pl_flags |= PLMETAL; /* OR in the metal flag */
110 if (!configvals->resource_bombing)
111 planets[t].pl_flags |= PLREPAIR;
112 }
113 for (i = 0; i < NDILYTH; i++)
114 { /* place the metal deposits */
115 t = lrand48() % (NUMPLANETS - SYSTEMS) + SYSTEMS; /* random planet */
116 planets[t].pl_flags |= PLDILYTH; /* OR in the dilyth flag */
117 planets[t].pl_flags &= ~(PLATMASK | PLARABLE); /* zero off previous
118 * atmos */
119 planets[t].pl_flags |= PLPOISON; /* dilyth poisons atmosphere */
120 if (!configvals->resource_bombing)
121 planets[t].pl_flags |= PLFUEL;
122 }
123 for (i = 0; i < NARABLE; i++)
124 { /* place the metal deposits */
125 t = lrand48() % (NUMPLANETS - SYSTEMS) + SYSTEMS; /* random planet */
126 planets[t].pl_flags |= PLARABLE | PLATYPE1; /* OR in the arable flag */
127 if (!configvals->resource_bombing)
128 planets[t].pl_flags |= PLAGRI;
129 }
130 }
131 #endif
132
133
134 #if 0
135 /*--------------------------------PLACESTARS------------------------------*/
136 /*
137 * This function places each system's star. The stars are expected to be in
138 * the first SYSTEMS number of planets. The coordinates of the stars are
139 * placed in the space grid.
140 */
141
142 static int
143 placestars()
144 {
145 int i, j; /* looping vars */
146 double x, y; /* to hold star coordinates */
147 int done; /* flag to indicate done */
148 double dx, dy; /* delta x and y's */
149 int attempts;
150
151 for (i = 0; i < SYSTEMS; i++)
152 { /* star for each system */
153 x = drand48() * GW; /* pick intial coords */
154 y = drand48() * GW;
155 attempts = 0;
156 do
157 { /* do until location found */
158 attempts++;
159 done = 0; /* not done yet */
160 x = fmod(x + 3574.0, GW); /* offset coords a little */
161 y = fmod(y + 134.0, GW); /* every loop */
162 if ((x > GW - STARBORD) || (x < STARBORD)
163 || (y < STARBORD) || (y > GW - STARBORD))
164 continue; /* too close to border? */
165 done = 1; /* assume valid cord found */
166 for (j = 0; j < i; j++)
167 { /* go through previous stars */
168 dx = fabs(x - (double) planets[j].pl_x);
169 dy = fabs(y - (double) planets[j].pl_y);
170 if (dx * dx + dy * dy < STARMIN2) /* if too close then */
171 done = 0; /* we must get another coord */
172 }
173 } while (!done && attempts < 1000); /* do until location found */
174
175 if (!done)
176 return 0;
177
178 planets[i].pl_owner = NOBODY; /* no team owns a star */
179 planets[i].pl_flags |= PLSTAR; /* mark planet as a star */
180 move_planet(i, (int) x, (int) y, 0);
181 planets[i].pl_system = i + 1; /* mark the sytem number */
182 planets[i].pl_hinfo = ALLTEAM; /* all teams know its a star */
183 for (j = 0; j < MAXTEAM + 1; j++)
184 { /* go put in info for teams */
185 planets[i].pl_tinfo[j].owner = NOBODY; /* nobody owns it */
186 planets[i].pl_tinfo[j].armies = 0;
187 planets[i].pl_tinfo[j].flags = planets[i].pl_flags;
188 }
189 }
190 return 1;
191 }
192 #endif
193
194
195
196 /*-----------------------------PLACESYSTEMS------------------------------*/
197 /*
198 * This function places the planets in each star's system. The function will
199 * return the index of the first planet that was not placed in a system. The
200 * coordinates of the planets are placed in the space grid.
201 */
202
203 static int
204 placesystems()
205 {
206 int i, j, k; /* looping vars */
207 double x, y; /* to hold star coordinates */
208 int done; /* flag to indicate done */
209 double dx, dy; /* delta x and y's */
210 int n; /* number of planet to place */
211 int np; /* number of planets in system */
212 int attempts;
213
214 n = SYSTEMS; /* first planet to place */
215 for (i = 0; i < SYSTEMS; i++)
216 { /* planets for each system */
217 np = SYSPLMIN + lrand48() % (SYSPLADD + 1); /* how many planets */
218 for (k = 0; k < np; k++)
219 { /* go place the planets */
220 attempts = 0;
221 do
222 { /* do until location found */
223 attempts++;
224 done = 0; /* not done yet */
225 dx = (drand48() * SYSWIDTH - SYSWIDTH / 2.0);
226 dy = (drand48() * SYSWIDTH - SYSWIDTH / 2.0);
227 if (dx * dx + dy * dy > (SYSWIDTH / 2.0) * (SYSWIDTH / 2.0))
228 continue; /* might orbit its way out of the galaxy */
229 x = planets[i].pl_x + dx;
230 y = planets[i].pl_y + dy;
231 if ((x > GW - SYSBORD) || (x < SYSBORD)
232 || (y < SYSBORD) || (y > GW - SYSBORD))
233 continue; /* too close to border? */
234
235 done = 1; /* assume valid coord found */
236 for (j = 0; j < n; j++)
237 { /* go through previous planets */
238 dx = fabs(x - (double) planets[j].pl_x);
239 dy = fabs(y - (double) planets[j].pl_y);
240 if (dx * dx + dy * dy < SYSMIN2)
241 { /* if too close to another star */
242 done = 0; /* we must get another coord */
243 }
244 }
245 } while (!done && attempts < 100); /* do until location found */
246
247 if (!done)
248 return 0; /* universe too crowded, try again */
249
250 move_planet(n, (int) x, (int) y, 0);
251 planets[n].pl_system = i + 1; /* mark the sytem number */
252 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY);
253 n++; /* go to next planet */
254 }
255 }
256 return (n); /* return index of next planet */
257 }
258
259
260
261
262 /*-----------------------------PLACEINDEP------------------------------*/
263 /*
264 * This function places idependent planets that are not in a system. They can
265 * appear anywhere in the galaxy as long as they are not too close to another
266 * planet. The coords are put in the space grid.
267 */
268
269 static int
270 placeindep(n)
271 int n;
272 /* number of planet to start with */
273 {
274 int i, j; /* looping vars */
275 double x, y; /* to hold star coordinates */
276 int done; /* flag to indicate done */
277 double dx, dy; /* delta x and y's */
278 int attempts;
279
280 for (i = n; i < (NUMPLANETS - (WORMPAIRS * 2)); i++)
281 {
282 /* go through rest of planets */
283 x = drand48() * GW; /* pick intial coords */
284 y = drand48() * GW;
285 attempts = 0;
286 do
287 { /* do until location found */
288 attempts++;
289 done = 0; /* not done yet */
290 x = fmod(x + 3574.0, GW); /* offset coords a little */
291 y = fmod(y + 134.0, GW); /* every loop */
292 if ((x > GW - SYSBORD) || (x < SYSBORD)
293 || (y < SYSBORD) || (y > GW - SYSBORD))
294 continue; /* too close to border? */
295 done = 1; /* assume valid coord */
296 for (j = 0; j < n; j++)
297 { /* go through previous planets */
298 dx = fabs(x - (double) planets[j].pl_x);
299 dy = fabs(y - (double) planets[j].pl_y);
300 if (dx * dx + dy * dy < SYSMIN2)
301 { /* if planet to close */
302 done = 0; /* we must get another coord */
303 }
304 }
305 } while (!done && attempts < 100); /* do until location found */
306
307 if (!done)
308 return 0;
309
310 move_planet(n, (int) x, (int) y, 0);
311 planets[n].pl_system = 0; /* mark the no sytem */
312 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY);
313 n++; /* go to next planet */
314 }
315 for (i = n; i < NUMPLANETS; i++) /* now place wormholes */
316 {
317 x = drand48() * GW; /* pick intial coords */
318 y = drand48() * GW;
319 attempts = 0;
320 do
321 { /* do until location found */
322 attempts++;
323 done = 0; /* not done yet */
324 x = fmod(x + 3574.0, GW); /* offset coords a little */
325 y = fmod(y + 1034.0, GW); /* every loop */
326 #if 0
327 if ((x > GW) || (y > GW))
328 continue; /* too close to border? */
329 #endif
330 done = 1; /* assume valid coord */
331 for (j = 0; j < n; j++)
332 { /* go through previous planets */
333 dx = fabs(x - (double) planets[j].pl_x);
334 dy = fabs(y - (double) planets[j].pl_y);
335 if (dx * dx + dy * dy < SYSMIN2)
336 { /* if planet to close */
337 done = 0; /* we must get another coord */
338 }
339 }
340 } while (!done && attempts < 200); /* do until location found */
341
342 if (!done)
343 return 0;
344
345 move_planet(n, (int) x, (int) y, 0);
346 planets[n].pl_system = 0; /* mark the no system */
347 planets[n].pl_flags |= PLWHOLE; /* mark the planet as a wormhole */
348 /* the armies in a wormhole is the other wormhole's x coord */
349 /* the radius is the other wormhole's y coord */
350 if (NUMPLANETS % 2)
351 {
352 if (!(n % 2))
353 {
354 planets[n].pl_armies = planets[n - 1].pl_x;
355 planets[n].pl_radius = planets[n - 1].pl_y;
356 planets[n - 1].pl_armies = planets[n].pl_x;
357 planets[n - 1].pl_radius = planets[n].pl_y;
358 }
359 }
360 else
361 {
362 if (n % 2)
363 {
364 planets[n].pl_armies = planets[n - 1].pl_x;
365 planets[n].pl_radius = planets[n - 1].pl_y;
366 planets[n - 1].pl_armies = planets[n].pl_x;
367 planets[n - 1].pl_radius = planets[n].pl_y;
368 }
369 }
370 planets[i].pl_owner = NOBODY; /* no team owns a star */
371 planets[i].pl_hinfo = ALLTEAM; /* all teams know its a star */
372 for (j = 0; j < MAXTEAM + 1; j++)
373 { /* go put in info for teams */
374 planets[i].pl_tinfo[j].owner = NOBODY; /* nobody owns it */
375 planets[i].pl_tinfo[j].armies = 0;
376 planets[i].pl_tinfo[j].flags = planets[i].pl_flags;
377 }
378 n++; /* go to next planet */
379 }
380 return 1;
381 }
382
383
384
385
386 /*---------------------------------PLACERACES------------------------------*/
387 /*
388 * This function places the races in the galaxy. Each race is placed in a
389 * different system. The race is given a home world with an Agri and Ship-
390 * yard on it and HOMEARMIES. They are also given a conoly planet with
391 * dilythium deposits and COLONYARMIES on it.
392 */
393
394 static void
395 placeraces()
396 {
397 int i, j, k; /* looping vars */
398 int p; /* to hold planet for race */
399
400 for (i = 0; i < 4; i++)
401 { /* go through races */
402 /* find home planet */
403 p = lrand48() % NUMPLANETS; /* pick random planet */
404 while ((planets[p].pl_system != i + 1)
405 || (PL_TYPE(planets[p]) == PLSTAR)
406 || (planets[p].pl_owner != NOBODY))
407 p = (p + 1) % NUMPLANETS; /* go on to next planet */
408 planets[p].pl_flags &= ~PLSURMASK; /* make sure no dilithium */
409 planets[p].pl_flags |= (PLMETAL | PLARABLE); /* metal and arable */
410 planets[p].pl_flags |= PLATYPE1; /* good atmosphere */
411 planets[p].pl_flags |= (PLAGRI | PLSHIPYARD | PLREPAIR);
412 planets[p].pl_tagri = PLGAGRI; /* set timers for resources */
413 planets[p].pl_tshiprepair = PLGSHIP;
414 planets[p].pl_owner = 1 << i; /* make race the owner */
415 #if 0 /* home planets do not have traditional names */
416 strcpy(planets[p].pl_name, homenames[1 << i]); /* set name and length */
417 planets[p].pl_namelen = strlen(homenames[1 << i]);
418 #endif
419 planets[p].pl_armies = HOMEARMIES; /* set the armies */
420 planets[p].pl_hinfo = 1 << i; /* race has info on planet */
421 planets[p].pl_tinfo[1 << i].owner = 1 << i; /* know about owner */
422 planets[p].pl_tinfo[1 << i].armies = planets[p].pl_armies;
423 planets[p].pl_tinfo[1 << i].flags = planets[p].pl_flags;
424 /* find colony planet */
425 p = lrand48() % NUMPLANETS; /* pick random planet */
426 while ((planets[p].pl_system != i + 1)
427 || (PL_TYPE(planets[p]) == PLSTAR)
428 || (planets[p].pl_owner != NOBODY))
429 p = (p + 1) % NUMPLANETS; /* go on to next planet */
430 planets[p].pl_flags |= PLFUEL; /* make fuel depot */
431 planets[p].pl_tfuel = PLGFUEL; /* set timer for fuel depot */
432 planets[p].pl_flags &= ~PLATMASK; /* take off previous atmos */
433 planets[p].pl_flags |= PLPOISON; /* poison atmosphere */
434 planets[p].pl_flags |= PLDILYTH; /* dilythium deposits */
435 planets[p].pl_owner = 1 << i; /* make race the owner */
436 planets[p].pl_armies = COLONYARMIES; /* set the armies */
437 planets[p].pl_hinfo = 1 << i; /* race knows about */
438 planets[p].pl_tinfo[1 << i].owner = 1 << i; /* know about owner */
439 planets[p].pl_tinfo[1 << i].armies = planets[p].pl_armies;
440 planets[p].pl_tinfo[1 << i].flags = planets[p].pl_flags;
441 for (j = 0; j < NUMPLANETS; j++)
442 {
443 if ((planets[j].pl_system == i + 1) && (PL_TYPE(planets[j]) != PLSTAR))
444 {
445 #ifdef LEAGUE_SUPPORT
446 for (k = (status2->league ? 0 : i);
447 k < (status2->league ? 4 : i + 1);
448 k++)
449 #else
450 k = i;
451 #endif
452 {
453 planets[j].pl_owner = 1 << i;
454 planets[j].pl_hinfo =
455 #ifdef LEAGUE_SUPPORT
456 status2->league ? (1 << 4) - 1 :
457 #endif
458 (1 << i);
459 planets[j].pl_tinfo[1 << k].owner = 1 << i;
460 planets[j].pl_tinfo[1 << k].armies = planets[j].pl_armies;
461 planets[j].pl_tinfo[1 << k].flags = planets[j].pl_flags;
462 }
463 }
464 }
465 }
466 }
467
468 /*
469 * Generate a complete galaxy. This is the algorithm used by the paradise
470 * 2.01 server in its first release. I hope.
471 */
472
473 void
474 gen_galaxy_1()
475 {
476 int t;
477 while (1)
478 {
479 NUMPLANETS = 60;
480 GWIDTH = 200000;
481 initplanets(); /* initialize planet structures */
482
483 /* place the resources */
484 zero_plflags(planets, NUMPLANETS);
485 randomize_atmospheres(planets + SYSTEMS, NUMPLANETS - SYSTEMS,
486 PATMOS1, PATMOS2, PATMOS3, PPOISON);
487 randomize_resources(planets + SYSTEMS, NUMPLANETS - SYSTEMS,
488 NMETAL, NDILYTH, NARABLE);
489
490 /* place system centers */
491 if (!place_stars(planets, SYSTEMS,
492 (int) STARBORD, (int) STARMIN, (int) GW,
493 (struct planet *) 0, 0))
494 continue;
495
496 t = placesystems(); /* place planets in systems */
497 if (!t)
498 continue;
499
500 if (!placeindep(t)) /* place independent planets */
501 continue;
502
503 break; /* success */
504 }
505 if (configvals->justify_galaxy)
506 justify_galaxy(SYSTEMS);
507
508 placeraces(); /* place home planets for races */
509 }