]> git.pond.sub.org Git - empserver/blob - src/util/perfect.c
Import of Empire 4.2.12
[empserver] / src / util / perfect.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23  *  related information and legal notices. It is expected that any future
24  *  projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  perfect.c: Create a perfect world
29  * 
30  *  Known contributors to this file:
31  *     James Anderson, 1986
32  *     Dave Pare, 1986
33  */
34
35 #if defined(aix) || defined(linux) || defined(solaris)
36 #include <unistd.h>
37 #endif /* aix or linux */
38
39 #include <stdio.h>
40 #include <fcntl.h>
41 #include "misc.h"
42 #include "var.h"
43 #include "sect.h"
44 #include "gamesdef.h"
45 #include "file.h"
46 #include "path.h"
47 #include "xy.h"
48 #include "prototypes.h"
49
50 #define XPLATES         (WORLD_X / 2)
51 #define YPLATES         WORLD_Y
52 #define YbyX            (YPLATES*XPLATES/8)
53
54 struct  sctstr sects[YPLATES*XPLATES];
55 u_char  s[YPLATES][XPLATES];
56 short   c[YPLATES][XPLATES];
57 short   e[YPLATES][XPLATES];
58 int     size[YbyX];
59 int     goldchance[YbyX];
60 int     ironchance[YbyX];
61 int     oilchance[YbyX];
62 int     fertchance[YbyX];
63 int     urchance[YbyX];
64
65 void    makec();
66 void    makeore();
67 int     nearelev();
68
69 int
70 main(argc, argp)
71         int     argc;
72         s_char  **argp;
73 {
74         register struct sctstr *sp;
75         register int y;
76         register int x;
77         int     sectf;
78         int     i;
79         time_t  now;
80         s_char  *sectfil = NULL;
81         extern char *optarg;
82         int opt;
83         char *config_file = NULL;
84         
85
86         while ((opt = getopt (argc, argp, "e:s:")) != EOF) {
87                 switch (opt) {
88                     case 'e':
89                         config_file = optarg;
90                         break;
91                     case 's':
92                         sectfil = optarg;
93                         break;
94                 }
95         }
96
97         emp_config (config_file);
98
99         if (sectfil == NULL)
100                 sectfil = empfile[EF_SECTOR].file;
101
102         time(&now);
103         srandom((unsigned int)now);
104         sectf = open(sectfil, O_RDWR, 0);
105         if (sectf < 0) {
106                 perror(sectfil);
107                 exit(1);
108         }
109         read(sectf, sects, sizeof(sects));
110         sp = sects;
111         for (y = 0; y < WORLD_Y; y++) {
112                 for (x = 0; x < WORLD_X; x++) {
113                         if (((x ^ y) & 1))
114                                 continue;
115                         c[y][x/2] = 0;
116                         s[y][x/2] = sp->sct_type;
117                         e[y][x/2] = sp->sct_elev;
118                         sp++;
119                 }
120         }
121         for (y = 0; y < WORLD_Y; y++) {
122                 for (x = 0; x < WORLD_X; x++) {
123                         if (((x ^ y) & 1))
124                                 continue;
125                         if (c[y][x/2] != 0)
126                                 continue;
127                         makec(x, y, 0);
128                 }
129         }
130         printf("size  oil  gold fert iron\n");
131         for (i=1; i<YbyX && size[i]; i++) {
132                 oilchance[i] =  5 + roll(75) - min(size[i] / 15, 10);
133 /*              goldchance[i] = 3 + roll(45) -  */
134                 goldchance[i] = 3 + roll(55) -
135                         (oilchance[i] + min(size[i] / 15, 10));
136 /*              urchance[i] = roll(40) - goldchance[i]; */
137                 urchance[i] = roll(30) - goldchance[i];
138                 fertchance[i] = roll(40) - (goldchance[i] + oilchance[i]);
139                 ironchance[i] = roll(45) - (goldchance[i] + oilchance[i]/2);
140                 if (size[i] > 10) {
141                         printf("%3d   %3d  %3d  %3d  %3d\n",
142                                 size[i], oilchance[i], goldchance[i],
143                                 fertchance[i], ironchance[i]);
144                 }
145         }
146         if (i == YbyX)
147                 printf("Oops.  YbyX not big enough\n");
148         sp = sects;
149         for (y = 0; y < WORLD_Y; y++) {
150                 for (x = 0; x < WORLD_X; x++) {
151                         if (((x ^ y) & 1))
152                                 continue;
153                         makeore(sp++);
154                 }
155         }
156         lseek(sectf, 0L, 0);
157         write(sectf, sects, sizeof(sects));
158         close(sectf);
159         exit(0);
160 }
161
162 int     cont = 0;
163
164 #define max(a,b) (a < b ? b : a)
165
166 void
167 makec(x, y, n)
168         int     x;
169         int     y;
170         int     n;
171 {
172         register int dy;
173         register int dx;
174         register int dir;
175         register short *cp;
176
177         if (s[y][x/2] == SCT_WATER)
178                 return;
179         cp = &c[y][x/2];
180         if (*cp != 0)
181                 return;
182         if (n == 0)
183                 n = ++cont;
184         *cp = n;
185         size[n]++;
186         for (dir = 1; dir <= 6; dir++) {
187                 dx = (diroff[dir][0] + x + WORLD_X) % WORLD_X;
188                 dy = (diroff[dir][1] + y + WORLD_Y) % WORLD_Y;
189                 makec(dx, dy, n);
190         }
191 }
192
193 void
194 makeore(sp)
195         register struct sctstr *sp;
196 {
197         int     elev;
198         int     oil, gmin, iron, fertil, ur;
199         int     lev;
200         int     i;
201         int     x,y;
202
203         y = sp->sct_y;
204         x = sp->sct_x;
205         elev = e[y][x/2];
206         lev = (elev*12 + nearelev(x, y))/18;
207         i = c[y][x/2];
208         oil = 0;
209         iron = 0;
210         gmin = 0;
211         fertil = 0;
212         ur = 0;
213         if (lev < 20 && lev > -15 && roll(100) < 30+oilchance[i]+lev) {
214                 oil = (45 - lev) + roll(50);
215                 if (oil > 100)
216                         oil = 100;
217                 if (oil < 10)
218                         oil = 0;
219         }
220         if (lev > 15 && roll(20+lev) < lev+ironchance[i]) {
221                 iron = lev + roll(55);
222                 if (iron > 100)
223                         iron = 100;
224                 if (iron < 10)
225                         iron = 0;
226         }
227         if (lev > 16 && roll(35+lev) < lev+goldchance[i]) {
228                 gmin = (lev - 5) + roll(45);
229                 if (gmin > 100)
230                         gmin = 100;
231                 if (gmin < 10)
232                         gmin = 0;
233         }
234         if (lev > 14 && roll(35+lev) < lev+urchance[i]) {
235                 ur = (lev - 5) + roll(45);
236                 if (ur > 100)
237                         ur = 100;
238                 if (ur < 10)
239                         ur = 0;
240         }
241         fertil = (85 + fertchance[i] - lev) - (((iron + gmin)/2) - oil/3);
242         if (fertil > 120)
243                 fertil = 120;
244         if (fertil < 0)
245                 fertil = 0;
246         sp->sct_oil = 100;
247         sp->sct_min = 100;
248         sp->sct_gmin = 100;
249         sp->sct_fertil = 100;
250         sp->sct_uran = 100;
251 }
252
253 int
254 nearelev(x, y)
255         int     x;
256         int     y;
257 {
258         int     dir;
259         int     dx;
260         int     dy;
261         int     level;
262
263         level = 0;
264         for (dir = 1; dir <= 6; dir++) {
265                 dx = (diroff[dir][0] + x + WORLD_X) % WORLD_X;
266                 dy = (diroff[dir][1] + y + WORLD_Y) % WORLD_Y;
267                 level += e[dy][dx/2];
268         }
269         return level;
270 }
271
272 /*              Already in libgen.a
273 roll(n)
274         int     n;
275 {
276         return random() % n;
277 }
278 */
279
280 int
281 min(a, b)
282         int     a;
283         int     b;
284 {
285         if (a < b)
286                 return a;
287         return b;
288 }