]> git.pond.sub.org Git - empserver/blob - src/util/perfect.c
ea2880c1e41f208edb42af852b5d74bc4deb2070
[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 }