comparison src/pl_gen0.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
21 #include <math.h>
22 #include <stdio.h>
23
24 #include "defs.h"
25 #include "struct.h"
26 #include "shmem.h"
27 #include "planets.h"
28
29 /*
30 * This file contains utility procedures useful when laying out the galaxy.
31 *
32 */
33
34 /* #define SLOWER */
35
36 int
37 place_stars(first, count, border, minpad, maxpad,
38 othercheck, ocount)
39 struct planet *first;
40 int count;
41 int border, minpad, maxpad;
42 struct planet *othercheck;
43 int ocount;
44 {
45 int i;
46 double x, y;
47
48 for (i = 0; i < count; i++)
49 {
50 int done, attempts;
51 int j;
52
53 attempts = 0;
54 done = 0;
55 #ifndef SLOWER
56 x = drand48() * (configvals->gwidth - 2 * border) + border;
57 y = drand48() * (configvals->gwidth - 2 * border) + border;
58 #endif
59 do
60 {
61
62 attempts++;
63
64 #ifdef SLOWER
65 x = drand48() * (configvals->gwidth - 2 * border) + border;
66 y = drand48() * (configvals->gwidth - 2 * border) + border;
67 #else
68 x = border + fmod(x + 3574 - border,
69 (configvals->gwidth - 2.0 * border));
70 y = border + fmod(y + 1034 - border,
71 (configvals->gwidth - 2.0 * border));
72 #endif
73 done = 1;
74 /* check to make sure we aren't too close to other stars */
75 for (j = 0; j < ocount; j++)
76 {
77 double dist = hypot(x - othercheck[j].pl_x,
78 y - othercheck[j].pl_y);
79 if (dist < minpad || dist > maxpad)
80 {
81 done = 0;
82 break;
83 }
84 }
85 /*
86 * check to make sure we're not too close to the current set of stars
87 */
88 if (done)
89 for (j = 0; j < i; j++)
90 {
91 double dist = hypot(x - first[j].pl_x,
92 y - first[j].pl_y);
93 if (dist < minpad || dist > maxpad)
94 {
95 done = 0;
96 break;
97 }
98 }
99 } while (!done && attempts < 1000);
100 if (!done)
101 return 0;
102
103 first[i].pl_owner = NOBODY;
104 first[i].pl_system = (&first[i] - planets) + 1;
105 first[i].pl_flags |= PLSTAR;
106 move_planet(&first[i] - planets, (int) x, (int) y, 0);
107 first[i].pl_hinfo = ALLTEAM;/* all teams know its a star */
108 for (j = 0; j < MAXTEAM + 1; j++)
109 { /* go put in info for teams */
110 first[i].pl_tinfo[j].owner = NOBODY; /* nobody owns it */
111 first[i].pl_tinfo[j].armies = 0;
112 first[i].pl_tinfo[j].flags = first[i].pl_flags;
113 }
114 }
115 return 1;
116 }
117
118 void
119 zero_plflags(first, count)
120 struct planet *first;
121 int count;
122 {
123 int i;
124 for (i = 0; i < count; i++)
125 {
126 first[i].pl_flags = 0;
127 }
128 }
129
130 void
131 randomize_atmospheres(first, count, p1, p2, p3, p4)
132 struct planet *first;
133 int count;
134 int p1, p2, p3, p4;
135 {
136 int i;
137 int sum = p1 + p2 + p3 + p4;
138 for (i = 0; i < count; i++)
139 {
140 int val;
141 int atmosphere;
142 val = lrand48() % sum;
143 if ((val -= p1) < 0)
144 atmosphere = PLATYPE1;
145 else if ((val -= p2) < 0)
146 atmosphere = PLATYPE2;
147 else if ((val -= p3) < 0)
148 atmosphere = PLATYPE3;
149 else
150 atmosphere = PLPOISON;
151 first[i].pl_flags &= !PLATMASK;
152 first[i].pl_flags |= atmosphere;
153 }
154 }
155
156 /*
157 * special note.
158 *
159 * It looks like this function originally wanted to make all Dilithium planets
160 * toxic, but the code was buggy and if an arable happened to be placed on
161 * the same planet later, you would get an STND DA.
162 *
163 * I am loath to fix this bug, because it would noticably alter the galactic
164 * mix. This must be brought before the PLC.
165 *
166 * -RF
167 *
168 */
169 void
170 randomize_resources(first, count, nm, nd, na)
171 struct planet *first;
172 int count;
173 int nm, nd, na;
174 {
175 for (; count > 0; count--, first++)
176 {
177 int val;
178
179 val = lrand48() % count;
180 if (val < nm)
181 {
182 nm--;
183 first->pl_flags |= PLMETAL;
184 if (!configvals->resource_bombing)
185 first->pl_flags |= PLREPAIR;
186 }
187
188 val = lrand48() % count;
189 if (val < nd)
190 {
191 nd--;
192 first->pl_flags |= PLDILYTH;
193 first->pl_flags &= ~(PLATMASK | PLARABLE);
194 first->pl_flags |= PLPOISON;
195 if (!configvals->resource_bombing)
196 first->pl_flags |= PLFUEL;
197 }
198
199 val = lrand48() % count;
200 if (val < na)
201 {
202 na--;
203 first->pl_flags |= PLARABLE | PLATYPE1;
204 if (!configvals->resource_bombing)
205 first->pl_flags |= PLAGRI;
206 }
207 }
208 }
209
210 static int
211 count_planets_in_system(sysnum)
212 int sysnum;
213 {
214 int rval = 0;
215 int i;
216
217 for (i = 0; i < NUMPLANETS; i++)
218 {
219 if (PL_TYPE(planets[i]) == PLPLANET &&
220 planets[i].pl_system == sysnum)
221 rval++;
222 }
223 return rval;
224 }
225
226 static int
227 pick_metal_planet_from_system(sysnum, nplanets)
228 int sysnum, nplanets;
229 {
230 int i;
231
232 for (i = 0; i < NUMPLANETS; i++)
233 {
234 if (PL_TYPE(planets[i]) == PLPLANET &&
235 planets[i].pl_system == sysnum &&
236 (planets[i].pl_flags & PLMETAL))
237 {
238 if (lrand48() % nplanets == 0)
239 return i;
240 nplanets--;
241 }
242 }
243 return -1;
244 }
245
246 static int
247 pick_planet_from_system(sysnum, nplanets)
248 int sysnum, nplanets;
249 {
250 int i;
251
252 if (nplanets < 0)
253 nplanets = count_planets_in_system(sysnum);
254
255 for (i = 0; i < NUMPLANETS; i++)
256 {
257 if (PL_TYPE(planets[i]) == PLPLANET &&
258 planets[i].pl_system == sysnum)
259 {
260 if (lrand48() % nplanets == 0)
261 return i;
262 nplanets--;
263 }
264 }
265 return -1;
266 }
267
268
269 void
270 justify_galaxy(numsystems)
271 int numsystems;
272 /*
273 * Balances the galaxy to be "fair". Currently ensures that: -> One metal
274 * planet exists within each system.
275 */
276 {
277 int i, j;
278 int *metalcount;
279
280 metalcount = malloc(sizeof(*metalcount) * (numsystems + 1));
281
282 for (i = 0; i <= numsystems; i++)
283 metalcount[i] = 0;
284
285 for (i = 0; i < NUMPLANETS; i++)
286 {
287 switch (PL_TYPE(planets[i]))
288 {
289 case PLPLANET:
290 {
291 int system = planets[i].pl_system;
292 if (system < 0 || system > numsystems)
293 break;
294 if (planets[i].pl_flags & PLMETAL)
295 metalcount[system]++;
296 }
297 break;
298 default:
299 ;
300 /* don't care about other stuff */
301 }
302 }
303
304 for (i = 1; i <= numsystems; i++)
305 {
306 if (metalcount[i] < 1)
307 {
308 int to, from;
309 int randbase;
310
311 randbase = lrand48() % (numsystems + 1);
312
313 for (j = 0; j <= numsystems; j++)
314 if (metalcount[(j + randbase) % (numsystems + 1)] > 1)
315 break;
316 if (j > numsystems)
317 {
318 fprintf(stderr, "error stealing metal planet. Too few!\n");
319 return;
320 }
321 j = (j + randbase) % (numsystems + 1);
322 to = pick_planet_from_system(i, -1);
323 from = pick_metal_planet_from_system(j, metalcount[j]);
324 planets[to].pl_flags |= PLMETAL;
325 planets[from].pl_flags &= ~PLMETAL;
326 if (!configvals->resource_bombing)
327 {
328 planets[to].pl_flags |= PLREPAIR;
329 planets[from].pl_flags &= PLREPAIR;
330 }
331 metalcount[i]++;
332 metalcount[j]--;
333 }
334 }
335 free(metalcount);
336 }