2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
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.
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.
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
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.
28 * fairland.c: Create a nice, new world
30 * Known contributors to this file:
37 /* define ORE 1 to add resources, define ORE 0 if you want to use another
38 program to add the resources */
42 /* If you don't specify these command line arguments, then these are the
44 #define DEFAULT_SPIKE 10
45 #define DEFAULT_MOUNTAIN 0
46 #define DEFAULT_CONTDIST 2
47 #define DEFAULT_ISLDIST 1
49 /* The following five numbers refer to elevation under which (in the case of
50 fertility or oil) or over which (in the case of iron, gold, and uranium)
51 sectors with that elevation will contain that resource. Elevation ranges
54 /* raise FERT_MAX for more fertility */
57 /* raise OIL_MAX for more oil */
60 /* lower IRON_MIN for more iron */
63 /* lower GOLD_MIN for more gold */
66 /* lower URAN_MIN for more uranium */
70 #include "../lib/gen/getopt.h"
85 #include "prototypes.h"
87 /* do not change these 4 defines */
88 #define LANDMIN 1 /* plate altitude for normal land */
89 #define HILLMIN 34 /* plate altitude for hills */
90 #define PLATMIN 36 /* plate altitude for plateau */
91 #define HIGHMIN 98 /* plate altitude for mountains */
93 static void qprint(const char * const fmt, ...)
94 ATTRIBUTE((format (printf, 1, 2)));
96 #define DEFAULT_OUTFILE_NAME "newcap_script"
97 static const char *outfile = DEFAULT_OUTFILE_NAME;
98 /* mark the continents with a * so you can tell them
99 from the islands 1 = mark, 0 = don't mark. */
100 static int AIRPORT_MARKER = 0;
102 /* don't let the islands crash into each other.
103 1 = don't merge, 0 = merge. */
104 static int DISTINCT_ISLANDS = 1;
106 static char *program_name;
108 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
109 #define YSIZE (WORLD_Y)
110 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
111 #define INFINITY 999 /* a number which means "BIG" */
113 /* these defines prevent infinite loops:
116 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
117 when growing continents and islands */
118 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
119 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
120 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
125 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
126 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
128 #define max(a,b) (a>b?a:b)
130 #define rnd(x) (random() % (x))
132 int secs; /* number of sectors grown */
133 int ctot; /* total number of continents and islands grown */
134 int *isecs; /* array of how large each island is */
136 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
137 unsigned long rnd_seed; /* optional seed can be passed as an argument */
138 int *capx, *capy; /* location of the nc capitals */
139 int *mc, mcc; /* array and counter used for stability
140 check when perturbing */
141 int spike; /* are we spiking? */
142 int mind; /* the final distance between capitals that
144 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
145 int diry[] = { 0, -1, -1, 0, 1, 1 };
147 int **own; /* owner of the sector. -1 means water */
148 int **elev; /* elevation of the sectors */
149 int **sectx, **secty; /* the sectors for each continent */
150 int **sectc; /* which sectors are on the coast? */
151 int *vector; /* used for measuring distances */
152 int *weight; /* used for placing mountains */
153 int *dsea, *dmoun; /* the dist to the ocean and mountain */
154 FILE *sect_fptr; /* the file we write everything to */
155 struct sctstr **sects;
156 struct sctstr *sectsbuf;
157 int fl_status; /* is anything wrong? */
158 #define STATUS_NO_ROOM 1 /* there was no room to grow */
159 #define NUMTRIES 10 /* keep trying to grow this many times */
161 const char *numletter =
162 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
164 static void help(char *);
165 static void usage(void);
166 static void parse_args(int argc, char *argv[]);
167 static int allocate_memory(void);
168 static void init(void);
169 static int drift(void);
170 static void grow_continents(void);
171 static void create_elevations(void);
172 static void write_sects(void);
173 static int write_file(void);
174 static void output(void);
175 static int write_newcap_script(void);
176 static int stable(void);
177 static void elevate_land(void);
178 static void elevate_sea(void);
179 static void translate_continents(void);
180 static int map_symbol(int x, int y);
181 static void fl_sct_init(coord x, coord y, s_char *ptr,
183 static void set_coastal_flags(void);
185 static void print_vars(void);
186 static void fl_move(int);
187 static void next_coast(int c, int x, int y, int *xp, int *yp);
188 static void grow_islands(void);
190 /****************************************************************************
192 ****************************************************************************/
195 main(int argc, char *argv[])
198 char *config_file = NULL;
201 program_name = argv[0];
202 rnd_seed = time(NULL);
204 while ((opt = getopt(argc, argv, "ae:hioqs:R:")) != EOF) {
210 DISTINCT_ISLANDS = 0;
213 config_file = optarg;
225 rnd_seed = strtoul(optarg, NULL, 10);
236 if (emp_config(config_file))
239 parse_args(argc - optind, argv + optind);
240 if (allocate_memory() == -1)
247 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
248 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
249 qprint("seed is %lu\n", rnd_seed);
250 qprint("placing capitals...\n");
252 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
253 qprint("growing continents...\n");
255 } while (fl_status && ++i < NUMTRIES);
257 fputs("ERROR: World not large enough to hold continents\n",
261 qprint("growing islands:");
263 qprint("\nelevating land...\n");
265 qprint("designating sectors...\n");
267 qprint("adding resources...\n");
269 qprint("writing to sectors file...\n");
270 if (write_file() == -1)
273 write_newcap_script();
275 qprint("\t*** Resources have not been added ***\n");
284 puts("Creating a planet with:\n");
285 printf("%d continents\n", nc);
286 printf("continent size: %d\n", sc);
287 printf("number of islands: %d\n", ni);
288 printf("average size of islands: %d\n", is);
289 printf("spike: %d%%\n", sp);
290 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
291 pm, (pm * sc) / 100);
292 printf("minimum distance between continents: %d\n", di);
293 printf("minimum distance from islands to continents: %d\n", id);
294 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
302 for (i = 1; i * i < n * 10000; ++i) ;
303 return (i + 50) / 100;
306 /****************************************************************************
307 PARSE COMMAND LINE ARGUMENTS
308 ****************************************************************************/
311 help(char *complaint)
314 fprintf(stderr, "%s: %s\n", program_name, complaint);
315 fprintf(stderr, "Try -h for help.\n");
321 printf("Usage: %s [-e CONFIG] [-aiqo] [-s SCRIPT] [-R SEED] NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
323 " -o don't set resources\n"
324 " -a airport marker for continents\n"
325 " -i islands may merge\n"
326 " -R SEED seed for random number generator\n"
327 " -e CONFIG configuration file\n"
328 " -s SCRIPT name of script to create (default %s)\n"
329 " NC number of continents\n"
330 " SC continent size\n"
331 " NI number of islands (default NC)\n"
332 " IS average island size (default SC/2)\n"
333 " SP spike percentage: 0 = round, 100 = snake\n"
335 " PM percentage of land that is mountain (default %d)\n"
336 " DI minimum distance between continents (default %d)\n"
337 " ID minimum distance from islands to continents (default %d)\n",
338 program_name, DEFAULT_OUTFILE_NAME,
339 DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
343 parse_args(int argc, char *argv[])
346 help("missing arguments");
350 help("too many arguments");
355 puts("fairland: error -- number of continents must be > 0");
361 puts("fairland: error -- size of continents must be > 0");
389 pm = DEFAULT_MOUNTAIN;
396 di = DEFAULT_CONTDIST;
399 puts("fairland: error -- distance between continents must be >= 0");
402 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
403 puts("fairland: error -- distance between continents too large");
410 id = DEFAULT_ISLDIST;
412 puts("fairland: error -- distance from islands to continents must be >= 0");
415 if (id > WORLD_X || id > WORLD_Y) {
416 puts("fairland: error -- distance from islands to continents too large");
419 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
420 puts("fairland: error -- world not big enough to fit continents.");
421 puts("arguments must satisfy:");
422 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
427 /****************************************************************************
428 VARIABLE INITIALIZATION
429 ****************************************************************************/
432 allocate_memory(void)
437 fname = malloc(strlen(datadir) + 1 + strlen(empfile[EF_SECTOR].file) + 1);
438 sprintf(fname, "%s/%s", datadir, empfile[EF_SECTOR].file);
439 sect_fptr = fopen(fname, "wb");
440 if (sect_fptr == NULL) {
445 sectsbuf = calloc((YSIZE * XSIZE), sizeof(struct sctstr));
446 sects = calloc(YSIZE, sizeof(struct sctstr *));
447 for (i = 0; i < YSIZE; i++)
448 sects[i] = §sbuf[XSIZE * i];
449 capx = calloc(nc, sizeof(int));
450 capy = calloc(nc, sizeof(int));
451 vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
452 mc = calloc(STABLE_CYCLE, sizeof(int));
453 own = calloc(WORLD_X, sizeof(int *));
454 elev = calloc(WORLD_X, sizeof(int *));
455 for (i = 0; i < WORLD_X; ++i) {
456 own[i] = calloc(WORLD_Y, sizeof(int));
457 elev[i] = calloc(WORLD_Y, sizeof(int));
459 sectx = calloc(nc + ni, sizeof(int *));
460 secty = calloc(nc + ni, sizeof(int *));
461 sectc = calloc(nc + ni, sizeof(int *));
462 isecs = calloc(nc + ni, sizeof(int));
463 weight = calloc(max(sc, is * 2), sizeof(int));
464 dsea = calloc(max(sc, is * 2), sizeof(int));
465 dmoun = calloc(max(sc, is * 2), sizeof(int));
466 for (i = 0; i < nc; ++i) {
467 sectx[i] = calloc(sc, sizeof(int));
468 secty[i] = calloc(sc, sizeof(int));
469 sectc[i] = calloc(sc, sizeof(int));
471 for (i = nc; i < nc + ni; ++i) {
472 sectx[i] = calloc(is * 2, sizeof(int));
473 secty[i] = calloc(is * 2, sizeof(int));
474 sectc[i] = calloc(is * 2, sizeof(int));
483 int i, j, xx = 0, yy = 0;
488 for (i = 0; i < WORLD_X; ++i) {
489 for (j = 0; j < WORLD_Y; ++j) {
491 elev[i][j] = -INFINITY;
495 for (i = 0; i < nc; ++i, xx += 2) {
500 puts("fairland error: world not big enough for all the continents.\n");
507 for (i = 0; i < STABLE_CYCLE; ++i)
511 /****************************************************************************
512 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
513 ****************************************************************************/
515 /* How isolated is capital j?
518 iso(int j, int newx, int newy)
520 int i, md, d = WORLD_X + WORLD_Y;
522 for (i = 0; i < nc; ++i) {
525 md = mapdist(capx[i], capy[i], newx, newy);
533 /* Drift all the capitals
540 for (turns = 0; turns < DRIFT_MAX; ++turns) {
541 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
543 for (i = 0; i < nc; ++i)
549 /* Check to see if we have stabilized--can we stop drifting the capitals?
555 int i, isod, d = 0, stab = 1;
557 for (i = 0; i < nc; ++i) {
558 isod = iso(i, capx[i], capy[i]);
562 for (i = 0; i < STABLE_CYCLE; ++i)
566 mcc = (mcc + 1) % STABLE_CYCLE;
570 /* This routine does the actual drifting
576 int i, n, newx, newy;
578 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
579 newx = new_x(capx[j] + dirx[i]);
580 newy = new_y(capy[j] + diry[i]);
581 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
589 /****************************************************************************
591 ****************************************************************************/
593 /* Look for a coastal sector of continent c
601 for (i = 0; i < secs; ++i) {
603 for (j = 0; j < 6; ++j)
604 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
609 /* Used for measuring distances
621 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
624 return i > 1 || vector[0] > 0;
627 /* Test to see if we're allowed to grow there: the arguments di and id
630 try_to_grow(int c, int newx, int newy, int d)
634 for (i = 1; i <= d; ++i) {
635 for (j = 0; j < i; ++j)
640 for (j = 0; j < i; ++j) {
641 px = new_x(px + dirx[vector[j]]);
642 py = new_y(py + diry[vector[j]]);
644 if (own[px][py] != -1 &&
646 (DISTINCT_ISLANDS || own[px][py] < nc))
648 } while (next_vector(i));
650 sectx[c][secs] = newx;
651 secty[c][secs] = newy;
656 /* Move along the coast in a clockwise direction.
660 next_coast(int c, int x, int y, int *xp, int *yp)
662 int i, nx, ny, wat = 0;
670 for (i = 0; i < 12; ++i) {
671 nx = new_x(x + dirx[i % 6]);
672 ny = new_y(y + diry[i % 6]);
673 if (own[nx][ny] == -1)
675 if (wat && own[nx][ny] == c) {
683 /* Choose a sector to grow from
695 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
700 } while (i != starti);
702 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
711 /* Grow continent c by 1 sector
715 grow_one_sector(int c)
717 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
719 spike = rnd(100) < sp;
720 if ((try1 = new_try(c)) == -1)
722 x = sx = sectx[c][try1];
723 y = sy = secty[c][try1];
728 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
729 newx = new_x(x + dirx[i]);
730 newy = new_y(y + diry[i]);
731 if (own[newx][newy] == -1 &&
733 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
734 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
735 if (try_to_grow(c, newx, newy, c < nc ? di : id))
739 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
740 newx = new_x(x + dirx[i]);
741 newy = new_y(y + diry[i]);
742 if (own[newx][newy] == -1)
743 if (try_to_grow(c, newx, newy, c < nc ? di : id))
746 next_coast(c, x, y, &x, &y);
748 } while (!done && coast_search < COAST_SEARCH_MAX &&
749 (secs == 1 || x != sx || y != sy));
750 if (!done && c < nc) {
751 qprint("fairland: error -- continent %c had no room to grow!\n",
753 fl_status |= STATUS_NO_ROOM;
758 /* Grow all the continents
761 grow_continents(void)
765 for (c = 0; c < nc; ++c) {
766 sectx[c][0] = capx[c];
767 secty[c][0] = capy[c];
768 own[sectx[c][0]][secty[c][0]] = c;
769 sectx[c][1] = new_x(capx[c] + 2);
770 secty[c][1] = capy[c];
771 own[sectx[c][1]][secty[c][1]] = c;
774 for (secs = 2; secs < sc && !fl_status; ++secs) {
775 for (c = 0; c < nc; ++c) {
780 for (c = 0; c < nc; ++c)
784 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
788 /****************************************************************************
790 ****************************************************************************/
792 /* Choose a place to start growing an island from
795 place_island(int c, int *xp, int *yp)
798 int ssy = rnd(WORLD_Y);
799 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
801 if (ssx > WORLD_X - 2)
802 ssx = new_x(ssx + 2);
803 for (d = di + id; d >= id; --d) {
807 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
808 if (*xp >= WORLD_X) {
809 *yp = new_y(*yp + 1);
811 if (*xp == sx && *yp == sy)
814 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
821 /* Grow all the islands
829 for (c = nc; c < nc + ni; ++c) {
831 if (!place_island(c, &x, &y))
833 isiz = 1 + rnd(2 * is - 1);
837 } while (secs < isiz && grow_one_sector(c));
839 qprint(" %d(%d)", c - nc + 1, secs);
845 /****************************************************************************
847 ****************************************************************************/
849 create_elevations(void)
855 /* Generic function for finding the distance to the closest sea, land, or
859 distance_to_what(int x, int y, int flag)
863 for (d = 1; d < 5; ++d) {
864 for (j = 0; j < d; ++j)
869 for (j = 0; j < d; ++j) {
870 px = new_x(px + dirx[vector[j]]);
871 py = new_y(py + diry[vector[j]]);
874 case 0: /* distance to sea */
875 if (own[px][py] == -1)
878 case 1: /* distance to land */
879 if (own[px][py] != -1)
882 case 2: /* distance to mountain */
883 if (elev[px][py] == INFINITY)
887 } while (next_vector(d));
892 #define ELEV elev[sectx[c][i]][secty[c][i]]
893 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
894 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
896 /* Decide where the mountains go
901 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
904 for (c = 0; c < ctot; ++c) {
906 ns = (c < nc) ? sc : isecs[c];
907 nm = (pm * ns) / 100;
909 /* Place the mountains */
911 for (i = 0; i < ns; ++i) {
912 dsea[i] = distance_to_sea();
913 weight[i] = (total += (dsea[i] * dsea[i]));
916 for (k = nm, mountain_search = 0;
917 k && mountain_search < MOUNTAIN_SEARCH_MAX;
920 for (i = 0; i < ns; ++i)
921 if (r < weight[i] && ELEV == -INFINITY &&
923 ((!(capx[c] == sectx[c][i] &&
924 capy[c] == secty[c][i])) &&
925 (!(new_x(capx[c] + 2) == sectx[c][i] &&
926 capy[c] == secty[c][i]))))) {
933 /* Elevate land that is not mountain and not capital */
935 for (i = 0; i < ns; ++i)
936 dmoun[i] = distance_to_mountain();
937 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
938 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
940 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
943 for (i = 0; i < ns; ++i) {
944 if (ELEV != INFINITY &&
945 (c >= nc || ((!(capx[c] == sectx[c][i] &&
946 capy[c] == secty[c][i])) &&
947 (!(new_x(capx[c] + 2) == sectx[c][i] &&
948 capy[c] == secty[c][i]))))) {
949 h = 3 * (5 - dmoun[i]) + dsea[i];
959 if (newk >= HILLMIN && newk < PLATMIN)
963 elev[sectx[c][where]][secty[c][where]] = newk;
964 dsea[where] = -INFINITY;
965 dmoun[where] = INFINITY;
968 /* Elevate the mountains and capitals */
970 for (i = 0; i < ns; ++i) {
971 if (ELEV == INFINITY) {
973 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
975 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
976 rnd((256 - HIGHMIN) / 2);
977 } else if ((c < nc &&
978 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
979 ((new_x(capx[c] + 2) == sectx[c][i] &&
980 capy[c] == secty[c][i])))
986 #define distance_to_land() distance_to_what(x, y, 1)
993 for (y = 0; y < WORLD_Y; ++y) {
994 for (x = y % 2; x < WORLD_X; x += 2) {
995 if (elev[x][y] == -INFINITY)
996 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
1001 /****************************************************************************
1003 ****************************************************************************/
1010 fert = LANDMIN - e + 40;
1011 else if (e < FERT_MAX)
1012 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1023 oil = (LANDMIN - e) * 2 + rnd(2);
1024 else if (e <= OIL_MAX)
1025 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1035 if (e >= IRON_MIN && e < HIGHMIN)
1036 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1046 if (e >= GOLD_MIN) {
1048 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1050 gold = 100 - 20 * HIGHMIN / e;
1061 if (e >= URAN_MIN && e < HIGHMIN)
1062 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1069 add_resources(struct sctstr *sct)
1071 sct->sct_fertil = set_fert(sct->sct_elev);
1072 sct->sct_oil = set_oil(sct->sct_elev);
1073 sct->sct_min = set_iron(sct->sct_elev);
1074 sct->sct_gmin = set_gold(sct->sct_elev);
1075 sct->sct_uran = set_uran(sct->sct_elev);
1078 /****************************************************************************
1079 DESIGNATE THE SECTORS
1080 ****************************************************************************/
1087 time_t current_time = time(NULL);
1089 /* sct = §s[0][0]; */
1091 for (y = 0; y < YSIZE; y++) {
1092 for (x = 0; x < XSIZE; x++, sct++) {
1093 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct, current_time);
1094 total = elev[sct->sct_x][y];
1095 if (total < LANDMIN) {
1096 sct->sct_type = SCT_WATER;
1097 } else if (total < HILLMIN)
1098 sct->sct_type = SCT_RURAL;
1099 else if (total < PLATMIN)
1100 sct->sct_type = SCT_MOUNT;
1101 else if (total < HIGHMIN)
1102 sct->sct_type = SCT_RURAL;
1104 sct->sct_type = SCT_MOUNT;
1105 sct->sct_elev = total;
1106 sct->sct_newtype = sct->sct_type;
1112 for (c = 0; c < nc; ++c) {
1113 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1114 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1116 set_coastal_flags();
1119 /****************************************************************************
1120 WRITE ALL THIS STUFF TO THE FILE
1121 ****************************************************************************/
1127 n = fwrite(sectsbuf, sizeof(struct sctstr), YSIZE * XSIZE, sect_fptr);
1129 perror(empfile[EF_SECTOR].file);
1132 if (n != YSIZE * XSIZE) {
1133 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1140 /****************************************************************************
1141 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1142 ****************************************************************************/
1148 translate_continents();
1150 for (i = 0; i < WORLD_Y; ++i) {
1154 for (j = i % 2; j < WORLD_X; j += 2) {
1155 if (own[j][i] == -1)
1158 printf("%c ", map_symbol(j, i));
1164 printf("\n\nEach continent is marked by a \"*\" on the map (to distinguish them from\nthe islands). You can redesignate these airfields to wilderness sectors\none at a time, each time you add a new country to the game.\n");
1167 /* Reorder the continents from top left to bottom right */
1169 translate_continents(void)
1171 int i, j, n = 0, k, gotit, c;
1172 int *trans, *trans_cont, *oldcapx, *oldcapy;
1174 trans = calloc(nc, sizeof(int));
1175 trans_cont = calloc(nc, sizeof(int));
1176 oldcapx = calloc(nc, sizeof(int));
1177 oldcapy = calloc(nc, sizeof(int));
1179 for (i = 0; i < WORLD_Y; ++i) {
1180 for (j = i % 2; j < WORLD_X; j += 2) {
1181 if (own[j][i] > -1 && own[j][i] < nc) {
1183 for (k = 0; k < n; ++k) {
1184 if (trans[k] == own[j][i])
1189 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1192 trans[n] = own[j][i];
1193 trans_cont[own[j][i]] = n;
1199 for (i = 0; i < WORLD_Y; ++i) {
1200 for (j = i % 2; j < WORLD_X; j += 2) {
1201 if (own[j][i] > -1 && own[j][i] < nc) {
1202 own[j][i] = trans_cont[own[j][i]];
1206 for (c = 0; c < nc; ++c) {
1207 oldcapx[c] = capx[c];
1208 oldcapy[c] = capy[c];
1210 for (c = 0; c < nc; ++c) {
1211 capx[c] = oldcapx[trans[c]];
1212 capy[c] = oldcapy[trans[c]];
1217 map_symbol(int x, int y)
1221 for (c = 0; c < nc; ++c)
1222 if ((x == capx[c] && y == capy[c])
1223 || (x == new_x(capx[c] + 2) && y == capy[c]))
1225 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1226 || elev[x][y] >= HIGHMIN)
1228 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1231 /***************************************************************************
1232 WRITE A SCRIPT FOR PLACING CAPITALS
1233 ****************************************************************************/
1235 write_newcap_script(void)
1238 FILE *script = fopen(outfile, "w");
1241 printf("fairland: error, unable to write to %s.\n", outfile);
1245 for (c = 0; c < nc; ++c) {
1246 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1248 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1249 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1251 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1254 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1260 qprint(const char * const fmt, ...)
1266 vfprintf(stdout, fmt, ap);
1272 fl_sct_init(coord x, coord y, s_char *ptr, time_t timestamp)
1274 struct sctstr *sp = (struct sctstr *)ptr;
1276 sp->ef_type = EF_SECTOR;
1283 sp->sct_defense = 0;
1284 sp->sct_timestamp = timestamp;
1285 sp->sct_coastal = 1;
1289 set_coastal_flags(void)
1293 qprint("setting coastal flags...\n");
1294 for (i = 0; i < nc; ++i)
1295 for (j = 0; j < sc; j++)
1296 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];
1297 for (i = nc; i < nc + ni; ++i)
1298 for (j = 0; j < isecs[i]; j++)
1299 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];