Mercurial > ~darius > hgwebdir.cgi > paradise_server
comparison src/pl_gen6.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 | |
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/4.5) /* 5.9 width of a system */ | |
29 | |
30 #define SYSTEMS 6 /* 9 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 13 /* number of metal deposits */ | |
40 #define NDILYTH 10 /* number of dilythium deposits */ | |
41 #define NARABLE 15 /* 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 (GW*0.27) | |
46 #define TEAMBORD (GW*0.32) | |
47 #define STARMIN (GW/5.6)/* min dist between stars */ | |
48 #define STARMAX GW | |
49 #define TEAMMIN (GW/2.8)/* min dist between team stars */ | |
50 #define TEAMMAX (GW/1.8)/* max dist between team stars */ | |
51 | |
52 /* defines that deal with systems and their planets */ | |
53 #define SYSADD 2 /* number possible above min number */ | |
54 #define SYSBORD (7000.0 + (float)GWIDTH/200) /* min distance from | |
55 * border wall */ | |
56 #define INDBORD (GW*0.23) | |
57 #define SYSMIN (5500.0 + (float)GWIDTH/200) /* min distance between | |
58 * objects */ | |
59 #define SYSMIN2 (SYSMIN*SYSMIN) /* square of sysmin distance */ | |
60 #define SYSPLMIN 9 /* 5 min number of planets for system */ | |
61 #define SYSPLADD 0 /* number of possible extra planets */ | |
62 #define MINARMY 5 /* 8 /* min numer of armies on a | |
63 * planet */ | |
64 #define MAXARMY 6 /* 15 /* max number of armies on a | |
65 * planet */ | |
66 | |
67 /* other defines */ | |
68 #define HOMEARMIES 30 /* number of armies on home planets */ | |
69 #define COLONYARMIES 10 /* number of armies for colony planet */ | |
70 | |
71 | |
72 /* defines dealing with growth timers */ | |
73 #define PLGFUEL configvals->plgrow.fuel /* time for growth of fuel | |
74 * depot */ | |
75 #define PLGAGRI configvals->plgrow.agri /* time for growth of agri */ | |
76 #define PLGREPAIR configvals->plgrow.repair /* time for growth of | |
77 * repair */ | |
78 #define PLGSHIP configvals->plgrow.shipyard /* time for growth of | |
79 * shipyard */ | |
80 | |
81 | |
82 /*-----------------------------PLACESYSTEMS------------------------------*/ | |
83 /* | |
84 * This function places the planets in each star's system. The function will | |
85 * return the index of the first planet that was not placed in a system. The | |
86 * coordinates of the planets are placed in the space grid. | |
87 */ | |
88 | |
89 static int | |
90 placesystems() | |
91 { | |
92 int i, j, k; /* looping vars */ | |
93 double x, y; /* to hold star coordinates */ | |
94 int done; /* flag to indicate done */ | |
95 double dx, dy; /* delta x and y's */ | |
96 int n; /* number of planet to place */ | |
97 int np; /* number of planets in system */ | |
98 int attempts; | |
99 | |
100 n = SYSTEMS; /* first planet to place */ | |
101 for (i = 0; i < SYSTEMS; i++) | |
102 { /* planets for each system */ | |
103 np = SYSPLMIN + lrand48() % (SYSPLADD + 1); /* how many planets */ | |
104 for (k = 0; k < np; k++) | |
105 { /* go place the planets */ | |
106 attempts = 0; | |
107 do | |
108 { /* do until location found */ | |
109 attempts++; | |
110 done = 0; /* not done yet */ | |
111 dx = (drand48() * SYSWIDTH - SYSWIDTH / 2.0); | |
112 dy = (drand48() * SYSWIDTH - SYSWIDTH / 2.0); | |
113 if (dx * dx + dy * dy > (SYSWIDTH / 2.0) * (SYSWIDTH / 2.0)) | |
114 continue; /* might orbit its way out of the galaxy */ | |
115 x = planets[i].pl_x + dx; | |
116 y = planets[i].pl_y + dy; | |
117 if ((x > GW - SYSBORD) || (x < SYSBORD) | |
118 || (y < SYSBORD) || (y > GW - SYSBORD)) | |
119 continue; /* too close to border? */ | |
120 | |
121 done = 1; /* assume valid coord found */ | |
122 for (j = 0; j < n; j++) | |
123 { /* go through previous planets */ | |
124 dx = fabs(x - (double) planets[j].pl_x); | |
125 dy = fabs(y - (double) planets[j].pl_y); | |
126 if (dx * dx + dy * dy < SYSMIN2) | |
127 { /* if too close to another star */ | |
128 done = 0; /* we must get another coord */ | |
129 } | |
130 } | |
131 } while (!done && attempts < 200); /* do until location found */ | |
132 | |
133 if (!done) | |
134 return 0; /* universe too crowded, try again */ | |
135 | |
136 move_planet(n, (int) x, (int) y, 0); | |
137 planets[n].pl_system = i + 1; /* mark the sytem number */ | |
138 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY); | |
139 n++; /* go to next planet */ | |
140 } | |
141 } | |
142 return (n); /* return index of next planet */ | |
143 } | |
144 | |
145 | |
146 | |
147 | |
148 /*-----------------------------PLACEINDEP------------------------------*/ | |
149 /* | |
150 * This function places idependent planets that are not in a system. They can | |
151 * appear anywhere in the galaxy as long as they are not too close to another | |
152 * planet. The coords are put in the space grid. | |
153 */ | |
154 | |
155 static int | |
156 placeindep(n) | |
157 int n; | |
158 /* number of planet to start with */ | |
159 { | |
160 int i, j; /* looping vars */ | |
161 double x, y; /* to hold star coordinates */ | |
162 int done; /* flag to indicate done */ | |
163 double dx, dy; /* delta x and y's */ | |
164 int attempts; | |
165 | |
166 for (i = n; i < (NUMPLANETS - (WORMPAIRS * 2)); i++) | |
167 { /* go through rest of planets */ | |
168 x = drand48() * (GW - 2 * INDBORD) + INDBORD; /* pick initial coords */ | |
169 y = drand48() * (GW - 2 * INDBORD) + INDBORD; | |
170 attempts = 0; | |
171 do | |
172 { /* do until location found */ | |
173 attempts++; | |
174 done = 0; /* not done yet */ | |
175 x = INDBORD + fmod(x + (3574.0 - INDBORD), GW - 2 * INDBORD); /* offset coords a | |
176 * little */ | |
177 y = INDBORD + fmod(y + (1034.0 - INDBORD), GW - 2 * INDBORD); /* every loop */ | |
178 #if 0 | |
179 if ((x > GW - INDBORD) || (x < INDBORD) | |
180 || (y < INDBORD) || (y > GW - INDBORD)) | |
181 continue; /* too close to border? */ | |
182 #endif | |
183 done = 1; /* assume valid coord */ | |
184 for (j = 0; j < n; j++) | |
185 { /* go through previous planets */ | |
186 dx = fabs(x - (double) planets[j].pl_x); | |
187 dy = fabs(y - (double) planets[j].pl_y); | |
188 if (dx * dx + dy * dy < SYSMIN2) | |
189 { /* if planet to close */ | |
190 done = 0; /* we must get another coord */ | |
191 } | |
192 } | |
193 } while (!done && attempts < 200); /* do until location found */ | |
194 | |
195 if (!done) | |
196 return 0; | |
197 | |
198 move_planet(n, (int) x, (int) y, 0); | |
199 planets[n].pl_system = 0; /* mark the no sytem */ | |
200 planets[n].pl_armies = MINARMY + lrand48() % (MAXARMY - MINARMY); | |
201 n++; /* go to next planet */ | |
202 } | |
203 for (i = n; i < NUMPLANETS; i++) /* now place wormholes */ | |
204 { | |
205 x = drand48() * GW; /* pick intial coords */ | |
206 y = drand48() * GW; | |
207 attempts = 0; | |
208 do | |
209 { /* do until location found */ | |
210 attempts++; | |
211 done = 0; /* not done yet */ | |
212 x = fmod(x + 3574.0, GW); /* offset coords a little */ | |
213 y = fmod(y + 1034.0, GW); /* every loop */ | |
214 #if 0 | |
215 if ((x > GW) || (y > GW)) | |
216 continue; /* too close to border? */ | |
217 #endif | |
218 done = 1; /* assume valid coord */ | |
219 for (j = 0; j < n; j++) | |
220 { /* go through previous planets */ | |
221 dx = fabs(x - (double) planets[j].pl_x); | |
222 dy = fabs(y - (double) planets[j].pl_y); | |
223 if (dx * dx + dy * dy < SYSMIN2) | |
224 { /* if planet to close */ | |
225 done = 0; /* we must get another coord */ | |
226 } | |
227 } | |
228 } while (!done && attempts < 200); /* do until location found */ | |
229 | |
230 if (!done) | |
231 return 0; | |
232 | |
233 move_planet(n, (int) x, (int) y, 0); | |
234 planets[n].pl_system = 0; /* mark the no system */ | |
235 planets[n].pl_flags |= PLWHOLE; /* mark the planet as a wormhole */ | |
236 /* the armies in a wormhole is the other wormhole's x coord */ | |
237 /* the radius is the other wormhole's y coord */ | |
238 if (NUMPLANETS % 2) | |
239 { | |
240 if (!(n % 2)) | |
241 { | |
242 planets[n].pl_armies = planets[n - 1].pl_x; | |
243 planets[n].pl_radius = planets[n - 1].pl_y; | |
244 planets[n - 1].pl_armies = planets[n].pl_x; | |
245 planets[n - 1].pl_radius = planets[n].pl_y; | |
246 } | |
247 } | |
248 else | |
249 { | |
250 if (n % 2) | |
251 { | |
252 planets[n].pl_armies = planets[n - 1].pl_x; | |
253 planets[n].pl_radius = planets[n - 1].pl_y; | |
254 planets[n - 1].pl_armies = planets[n].pl_x; | |
255 planets[n - 1].pl_radius = planets[n].pl_y; | |
256 } | |
257 } | |
258 planets[i].pl_owner = NOBODY; /* no team owns a star */ | |
259 planets[i].pl_hinfo = ALLTEAM; /* all teams know its a star */ | |
260 for (j = 0; j < MAXTEAM + 1; j++) | |
261 { /* go put in info for teams */ | |
262 planets[i].pl_tinfo[j].owner = NOBODY; /* nobody owns it */ | |
263 planets[i].pl_tinfo[j].armies = 0; | |
264 planets[i].pl_tinfo[j].flags = planets[i].pl_flags; | |
265 } | |
266 n++; /* go to next planet */ | |
267 } | |
268 return 1; | |
269 } | |
270 | |
271 | |
272 | |
273 | |
274 /*---------------------------------PLACERACES------------------------------*/ | |
275 /* | |
276 * This function places the races in the galaxy. Each race is placed in a | |
277 * different system. The race is given a home world with an Agri and Ship- | |
278 * yard on it and HOMEARMIES. They are also given a conoly planet with | |
279 * dilythium deposits and COLONYARMIES on it. | |
280 */ | |
281 | |
282 static void | |
283 placeraces() | |
284 { | |
285 int i, j, k, x; /* looping vars */ | |
286 int p; /* to hold planet for race */ | |
287 int r[4], t; | |
288 | |
289 r[0] = r[1] = lrand48() % 4; /* pick two races at random. They will be */ | |
290 while (r[0] == r[1]) /* the races whose systems are 'optimally' */ | |
291 r[1] = lrand48() % 4; /* placed. */ | |
292 i = 0; | |
293 while (i == r[0] || i == r[1]) | |
294 i++; | |
295 r[2] = i++; | |
296 while (i == r[0] || i == r[1]) | |
297 i++; | |
298 r[3] = i; | |
299 | |
300 /* only allow these teams */ | |
301 status2->nontteamlock = (1 << r[0]) | (1 << r[1]); | |
302 | |
303 for (i = 0; i < 4; i++) | |
304 { /* go through races */ | |
305 t = r[i]; /* which team */ | |
306 p = lrand48() % NUMPLANETS; /* pick random planet */ | |
307 /* for (x=0; x <= 1; x++) { /* loop twice for 2 systems */ | |
308 while ((planets[p].pl_system != i + 1) | |
309 || (PL_TYPE(planets[p]) == PLSTAR) | |
310 || (planets[p].pl_owner != NOBODY)) | |
311 p = (p + 1) % NUMPLANETS; /* go on to next planet */ | |
312 | |
313 planets[p].pl_flags &= ~PLSURMASK; /* make sure no dilithium */ | |
314 planets[p].pl_flags |= (PLMETAL | PLARABLE); /* metal and arable */ | |
315 planets[p].pl_flags |= PLATYPE1; /* good atmosphere */ | |
316 planets[p].pl_flags |= (PLAGRI | PLSHIPYARD | PLREPAIR); | |
317 planets[p].pl_tagri = PLGAGRI; /* set timers for resources */ | |
318 planets[p].pl_tshiprepair = PLGSHIP; | |
319 planets[p].pl_owner = 1 << t; /* make race the owner */ | |
320 planets[p].pl_armies = HOMEARMIES; /* set the armies */ | |
321 planets[p].pl_hinfo = 1 << t; /* race has info on planet */ | |
322 planets[p].pl_tinfo[1 << t].owner = 1 << t; /* know about owner */ | |
323 planets[p].pl_tinfo[1 << t].armies = planets[p].pl_armies; | |
324 planets[p].pl_tinfo[1 << t].flags = planets[p].pl_flags; | |
325 | |
326 /* find colony planet */ | |
327 p = lrand48() % NUMPLANETS; /* pick random planet */ | |
328 while ((planets[p].pl_system != i + 1) | |
329 || (PL_TYPE(planets[p]) == PLSTAR) | |
330 || (planets[p].pl_owner != NOBODY)) | |
331 p = (p + 1) % NUMPLANETS; /* go on to next planet */ | |
332 planets[p].pl_flags |= PLFUEL; /* make fuel depot */ | |
333 planets[p].pl_tfuel = PLGFUEL; /* set timer for fuel depot */ | |
334 planets[p].pl_flags &= ~PLATMASK; /* take off previous atmos */ | |
335 planets[p].pl_flags |= PLPOISON; /* poison atmosphere */ | |
336 planets[p].pl_flags |= PLDILYTH; /* dilythium deposits */ | |
337 planets[p].pl_owner = 1 << t; /* make race the owner */ | |
338 planets[p].pl_armies = COLONYARMIES; /* set the armies */ | |
339 planets[p].pl_hinfo = 1 << t; /* race knows about */ | |
340 planets[p].pl_tinfo[1 << t].owner = 1 << t; /* know about owner */ | |
341 planets[p].pl_tinfo[1 << t].armies = planets[p].pl_armies; | |
342 planets[p].pl_tinfo[1 << t].flags = planets[p].pl_flags; | |
343 for (j = 0; j < NUMPLANETS; j++) | |
344 { | |
345 if ((planets[j].pl_system == i + 1) | |
346 && (PL_TYPE(planets[j]) != PLSTAR)) | |
347 { | |
348 #ifdef LEAGUE_SUPPORT | |
349 for (k = (status2->league ? 0 : t); | |
350 k < (status2->league ? 4 : t + 1); | |
351 k++) | |
352 #else | |
353 k = t; | |
354 #endif | |
355 { | |
356 planets[j].pl_owner = 1 << t; | |
357 planets[j].pl_hinfo = | |
358 #ifdef LEAGUE_SUPPORT | |
359 status2->league ? (1 << 4) - 1 : | |
360 #endif | |
361 (1 << t); | |
362 planets[j].pl_tinfo[1 << k].owner = 1 << t; | |
363 planets[j].pl_tinfo[1 << k].armies = planets[j].pl_armies; | |
364 planets[j].pl_tinfo[1 << k].flags = planets[j].pl_flags; | |
365 } | |
366 } | |
367 } | |
368 } | |
369 } | |
370 | |
371 /* | |
372 * Generate a complete galaxy. This variation is similar to gen_galaxy_1; | |
373 * except that it tries to place the races at consistent distances from one | |
374 * another. | |
375 */ | |
376 | |
377 void | |
378 gen_galaxy_6() | |
379 { | |
380 int t; | |
381 | |
382 NUMPLANETS = 60; /* planets + wormholes */ | |
383 GWIDTH = 200000; | |
384 | |
385 while (1) | |
386 { | |
387 initplanets(); /* initialize planet structures */ | |
388 | |
389 /* place the resources */ | |
390 zero_plflags(planets, NUMPLANETS); | |
391 randomize_atmospheres(planets + SYSTEMS, NUMPLANETS - SYSTEMS, | |
392 PATMOS1, PATMOS2, PATMOS3, PPOISON); | |
393 randomize_resources(planets + SYSTEMS, NUMPLANETS - SYSTEMS, | |
394 NMETAL, NDILYTH, NARABLE); | |
395 | |
396 /* place system centers */ | |
397 t = place_stars(planets, 2, | |
398 (int) TEAMBORD, (int) TEAMMIN, (int) TEAMMAX, | |
399 (struct planet *) 0, 0) | |
400 && place_stars(planets + 2, 2, | |
401 (int) (STARBORD * 0.8), (int) TEAMMIN, (int) STARMAX, | |
402 planets, 2) | |
403 && place_stars(planets + 4, SYSTEMS - 4, | |
404 (int) STARBORD, (int) STARMIN, (int) STARMAX, | |
405 planets, 4); | |
406 | |
407 if (!t) | |
408 continue; | |
409 t = placesystems(); /* place planets in systems */ | |
410 if (!t) | |
411 continue; | |
412 t = placeindep(t); /* place independent planets */ | |
413 if (t) | |
414 break; /* success */ | |
415 } | |
416 if (configvals->justify_galaxy) | |
417 justify_galaxy(SYSTEMS); | |
418 placeraces(); /* place home planets for races */ | |
419 } |