2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2008, 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 files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future 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 */
77 #include "prototypes.h"
82 /* do not change these 4 defines */
83 #define LANDMIN 1 /* plate altitude for normal land */
84 #define HILLMIN 34 /* plate altitude for hills */
85 #define PLATMIN 36 /* plate altitude for plateau */
86 #define HIGHMIN 98 /* plate altitude for mountains */
88 static void qprint(const char * const fmt, ...)
89 ATTRIBUTE((format (printf, 1, 2)));
91 #define DEFAULT_OUTFILE_NAME "newcap_script"
92 static const char *outfile = DEFAULT_OUTFILE_NAME;
93 /* mark the continents with a * so you can tell them
94 from the islands 1 = mark, 0 = don't mark. */
95 static int AIRPORT_MARKER = 0;
97 /* don't let the islands crash into each other.
98 1 = don't merge, 0 = merge. */
99 static int DISTINCT_ISLANDS = 1;
101 static char *program_name;
103 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
104 #define YSIZE (WORLD_Y)
105 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
106 #define INFINITY 999 /* a number which means "BIG" */
108 /* these defines prevent infinite loops:
111 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
112 when growing continents and islands */
113 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
114 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
115 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
120 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
121 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
122 #define rnd(x) (random() % (x))
124 int secs; /* number of sectors grown */
125 int ctot; /* total number of continents and islands grown */
126 int *isecs; /* array of how large each island is */
128 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
129 unsigned long rnd_seed; /* optional seed can be passed as an argument */
130 int *capx, *capy; /* location of the nc capitals */
131 int *mc, mcc; /* array and counter used for stability
132 check when perturbing */
133 int spike; /* are we spiking? */
134 int mind; /* the final distance between capitals that
136 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
137 int diry[] = { 0, -1, -1, 0, 1, 1 };
139 int **own; /* owner of the sector. -1 means water */
140 int **elev; /* elevation of the sectors */
141 int **sectx, **secty; /* the sectors for each continent */
142 int **sectc; /* which sectors are on the coast? */
143 int *vector; /* used for measuring distances */
144 int *weight; /* used for placing mountains */
145 int *dsea, *dmoun; /* the dist to the ocean and mountain */
146 FILE *sect_fptr; /* the file we write everything to */
147 struct sctstr **sects;
148 struct sctstr *sectsbuf;
149 int fl_status; /* is anything wrong? */
150 #define STATUS_NO_ROOM 1 /* there was no room to grow */
151 #define NUMTRIES 10 /* keep trying to grow this many times */
153 const char *numletter =
154 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
156 static void help(char *);
157 static void usage(void);
158 static void parse_args(int argc, char *argv[]);
159 static int allocate_memory(void);
160 static void init(void);
161 static int drift(void);
162 static void grow_continents(void);
163 static void create_elevations(void);
164 static void write_sects(void);
165 static int write_file(void);
166 static void output(void);
167 static int write_newcap_script(void);
168 static int stable(void);
169 static void elevate_land(void);
170 static void elevate_sea(void);
171 static int map_symbol(int x, int y);
172 static void fl_sct_init(coord, coord, struct sctstr *);
173 static void set_coastal_flags(void);
175 static void print_vars(void);
176 static void fl_move(int);
177 static void next_coast(int c, int x, int y, int *xp, int *yp);
178 static void grow_islands(void);
180 /****************************************************************************
182 ****************************************************************************/
185 main(int argc, char *argv[])
188 char *config_file = NULL;
191 program_name = argv[0];
192 rnd_seed = time(NULL);
194 while ((opt = getopt(argc, argv, "ae:hioqR:s:v")) != EOF) {
200 config_file = optarg;
203 DISTINCT_ISLANDS = 0;
212 rnd_seed = strtoul(optarg, NULL, 10);
221 printf("%s\n\n%s", version, legal);
229 if (emp_config(config_file))
232 parse_args(argc - optind, argv + optind);
233 if (allocate_memory() == -1)
240 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
241 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
242 qprint("seed is %lu\n", rnd_seed);
243 qprint("placing capitals...\n");
245 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
246 qprint("growing continents...\n");
248 } while (fl_status && ++i < NUMTRIES);
250 fputs("ERROR: World not large enough to hold continents\n",
254 qprint("growing islands:");
256 qprint("\nelevating land...\n");
258 qprint("designating sectors...\n");
260 qprint("adding resources...\n");
262 qprint("writing to sectors file...\n");
263 if (write_file() == -1)
266 write_newcap_script();
268 qprint("\t*** Resources have not been added ***\n");
277 puts("Creating a planet with:\n");
278 printf("%d continents\n", nc);
279 printf("continent size: %d\n", sc);
280 printf("number of islands: %d\n", ni);
281 printf("average size of islands: %d\n", is);
282 printf("spike: %d%%\n", sp);
283 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
284 pm, (pm * sc) / 100);
285 printf("minimum distance between continents: %d\n", di);
286 printf("minimum distance from islands to continents: %d\n", id);
287 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
295 for (i = 1; i * i < n * 10000; ++i) ;
296 return (i + 50) / 100;
299 /****************************************************************************
300 PARSE COMMAND LINE ARGUMENTS
301 ****************************************************************************/
304 help(char *complaint)
307 fprintf(stderr, "%s: %s\n", program_name, complaint);
308 fprintf(stderr, "Try -h for help.\n");
314 printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
315 " -a airport marker for continents\n"
316 " -e CONFIG-FILE configuration file\n"
318 " -h display this help and exit\n"
319 " -i islands may merge\n"
320 " -o don't set resources\n"
322 " -R SEED seed for random number generator\n"
323 " -s SCRIPT name of script to create (default %s)\n"
324 " NC number of continents\n"
325 " SC continent size\n"
326 " NI number of islands (default NC)\n"
327 " IS average island size (default SC/2)\n"
328 " SP spike percentage: 0 = round, 100 = snake (default %d)\n"
329 " PM percentage of land that is mountain (default %d)\n"
330 " DI minimum distance between continents (default %d)\n"
331 " ID minimum distance from islands to continents (default %d)\n",
332 program_name, dflt_econfig, DEFAULT_OUTFILE_NAME,
333 DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
337 parse_args(int argc, char *argv[])
340 help("missing arguments");
344 help("too many arguments");
349 puts("fairland: error -- number of continents must be > 0");
355 puts("fairland: error -- size of continents must be > 0");
383 pm = DEFAULT_MOUNTAIN;
390 di = DEFAULT_CONTDIST;
393 puts("fairland: error -- distance between continents must be >= 0");
396 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
397 puts("fairland: error -- distance between continents too large");
404 id = DEFAULT_ISLDIST;
406 puts("fairland: error -- distance from islands to continents must be >= 0");
409 if (id > WORLD_X || id > WORLD_Y) {
410 puts("fairland: error -- distance from islands to continents too large");
413 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
414 puts("fairland: error -- world not big enough to fit continents.");
415 puts("arguments must satisfy:");
416 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
421 /****************************************************************************
422 VARIABLE INITIALIZATION
423 ****************************************************************************/
426 allocate_memory(void)
431 fname = malloc(strlen(gamedir) + 1 + strlen(empfile[EF_SECTOR].file) + 1);
432 sprintf(fname, "%s/%s", gamedir, empfile[EF_SECTOR].file);
433 sect_fptr = fopen(fname, "wb");
434 if (sect_fptr == NULL) {
439 sectsbuf = calloc((YSIZE * XSIZE), sizeof(struct sctstr));
440 sects = calloc(YSIZE, sizeof(struct sctstr *));
441 for (i = 0; i < YSIZE; i++)
442 sects[i] = §sbuf[XSIZE * i];
443 capx = calloc(nc, sizeof(int));
444 capy = calloc(nc, sizeof(int));
445 vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
446 mc = calloc(STABLE_CYCLE, sizeof(int));
447 own = calloc(WORLD_X, sizeof(int *));
448 elev = calloc(WORLD_X, sizeof(int *));
449 for (i = 0; i < WORLD_X; ++i) {
450 own[i] = calloc(WORLD_Y, sizeof(int));
451 elev[i] = calloc(WORLD_Y, sizeof(int));
453 sectx = calloc(nc + ni, sizeof(int *));
454 secty = calloc(nc + ni, sizeof(int *));
455 sectc = calloc(nc + ni, sizeof(int *));
456 isecs = calloc(nc + ni, sizeof(int));
457 weight = calloc(MAX(sc, is * 2), sizeof(int));
458 dsea = calloc(MAX(sc, is * 2), sizeof(int));
459 dmoun = calloc(MAX(sc, is * 2), sizeof(int));
460 for (i = 0; i < nc; ++i) {
461 sectx[i] = calloc(sc, sizeof(int));
462 secty[i] = calloc(sc, sizeof(int));
463 sectc[i] = calloc(sc, sizeof(int));
465 for (i = nc; i < nc + ni; ++i) {
466 sectx[i] = calloc(is * 2, sizeof(int));
467 secty[i] = calloc(is * 2, sizeof(int));
468 sectc[i] = calloc(is * 2, sizeof(int));
477 int i, j, xx = 0, yy = 0;
482 for (i = 0; i < WORLD_X; ++i) {
483 for (j = 0; j < WORLD_Y; ++j) {
485 elev[i][j] = -INFINITY;
489 for (i = 0; i < nc; ++i) {
494 puts("fairland error: world not big enough for all the continents.\n");
502 for (i = 0; i < STABLE_CYCLE; ++i)
506 /****************************************************************************
507 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
508 ****************************************************************************/
510 /* How isolated is capital j?
513 iso(int j, int newx, int newy)
515 int i, md, d = WORLD_X + WORLD_Y;
517 for (i = 0; i < nc; ++i) {
520 md = mapdist(capx[i], capy[i], newx, newy);
528 /* Drift all the capitals
535 for (turns = 0; turns < DRIFT_MAX; ++turns) {
536 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
538 for (i = 0; i < nc; ++i)
544 /* Check to see if we have stabilized--can we stop drifting the capitals?
550 int i, isod, d = 0, stab = 1;
552 for (i = 0; i < nc; ++i) {
553 isod = iso(i, capx[i], capy[i]);
557 for (i = 0; i < STABLE_CYCLE; ++i)
561 mcc = (mcc + 1) % STABLE_CYCLE;
565 /* This routine does the actual drifting
571 int i, n, newx, newy;
573 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
574 newx = new_x(capx[j] + dirx[i]);
575 newy = new_y(capy[j] + diry[i]);
576 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
584 /****************************************************************************
586 ****************************************************************************/
588 /* Look for a coastal sector of continent c
596 for (i = 0; i < secs; ++i) {
598 for (j = 0; j < 6; ++j)
599 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
604 /* Used for measuring distances
616 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
619 return i > 1 || vector[0] > 0;
622 /* Test to see if we're allowed to grow there: the arguments di and id
625 try_to_grow(int c, int newx, int newy, int d)
629 for (i = 1; i <= d; ++i) {
630 for (j = 0; j < i; ++j)
635 for (j = 0; j < i; ++j) {
636 px = new_x(px + dirx[vector[j]]);
637 py = new_y(py + diry[vector[j]]);
639 if (own[px][py] != -1 &&
641 (DISTINCT_ISLANDS || own[px][py] < nc))
643 } while (next_vector(i));
645 sectx[c][secs] = newx;
646 secty[c][secs] = newy;
651 /* Move along the coast in a clockwise direction.
655 next_coast(int c, int x, int y, int *xp, int *yp)
657 int i, nx, ny, wat = 0;
665 for (i = 0; i < 12; ++i) {
666 nx = new_x(x + dirx[i % 6]);
667 ny = new_y(y + diry[i % 6]);
668 if (own[nx][ny] == -1)
670 if (wat && own[nx][ny] == c) {
678 /* Choose a sector to grow from
690 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
695 } while (i != starti);
697 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
706 /* Grow continent c by 1 sector
710 grow_one_sector(int c)
712 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
714 spike = rnd(100) < sp;
715 if ((try1 = new_try(c)) == -1)
717 x = sx = sectx[c][try1];
718 y = sy = secty[c][try1];
723 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
724 newx = new_x(x + dirx[i]);
725 newy = new_y(y + diry[i]);
726 if (own[newx][newy] == -1 &&
728 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
729 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
730 if (try_to_grow(c, newx, newy, c < nc ? di : id))
734 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
735 newx = new_x(x + dirx[i]);
736 newy = new_y(y + diry[i]);
737 if (own[newx][newy] == -1)
738 if (try_to_grow(c, newx, newy, c < nc ? di : id))
741 next_coast(c, x, y, &x, &y);
743 } while (!done && coast_search < COAST_SEARCH_MAX &&
744 (secs == 1 || x != sx || y != sy));
745 if (!done && c < nc) {
746 qprint("fairland: error -- continent %c had no room to grow!\n",
748 fl_status |= STATUS_NO_ROOM;
753 /* Grow all the continents
756 grow_continents(void)
760 for (c = 0; c < nc; ++c) {
761 sectx[c][0] = capx[c];
762 secty[c][0] = capy[c];
763 own[sectx[c][0]][secty[c][0]] = c;
764 sectx[c][1] = new_x(capx[c] + 2);
765 secty[c][1] = capy[c];
766 own[sectx[c][1]][secty[c][1]] = c;
769 for (secs = 2; secs < sc && !fl_status; ++secs) {
770 for (c = 0; c < nc; ++c) {
775 for (c = 0; c < nc; ++c)
779 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
783 /****************************************************************************
785 ****************************************************************************/
787 /* Choose a place to start growing an island from
790 place_island(int c, int *xp, int *yp)
793 int ssy = rnd(WORLD_Y);
794 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
796 if (ssx > WORLD_X - 2)
797 ssx = new_x(ssx + 2);
798 for (d = di + id; d >= id; --d) {
802 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
803 if (*xp >= WORLD_X) {
804 *yp = new_y(*yp + 1);
806 if (*xp == sx && *yp == sy)
809 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
816 /* Grow all the islands
824 for (c = nc; c < nc + ni; ++c) {
826 if (!place_island(c, &x, &y))
828 isiz = 1 + rnd(2 * is - 1);
832 } while (secs < isiz && grow_one_sector(c));
834 qprint(" %d(%d)", c - nc + 1, secs);
840 /****************************************************************************
842 ****************************************************************************/
844 create_elevations(void)
850 /* Generic function for finding the distance to the closest sea, land, or
854 distance_to_what(int x, int y, int flag)
858 for (d = 1; d < 5; ++d) {
859 for (j = 0; j < d; ++j)
864 for (j = 0; j < d; ++j) {
865 px = new_x(px + dirx[vector[j]]);
866 py = new_y(py + diry[vector[j]]);
869 case 0: /* distance to sea */
870 if (own[px][py] == -1)
873 case 1: /* distance to land */
874 if (own[px][py] != -1)
877 case 2: /* distance to mountain */
878 if (elev[px][py] == INFINITY)
882 } while (next_vector(d));
887 #define ELEV elev[sectx[c][i]][secty[c][i]]
888 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
889 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
891 /* Decide where the mountains go
896 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
899 for (c = 0; c < ctot; ++c) {
901 ns = (c < nc) ? sc : isecs[c];
902 nm = (pm * ns) / 100;
904 /* Place the mountains */
906 for (i = 0; i < ns; ++i) {
907 dsea[i] = distance_to_sea();
908 weight[i] = (total += (dsea[i] * dsea[i]));
911 for (k = nm, mountain_search = 0;
912 k && mountain_search < MOUNTAIN_SEARCH_MAX;
915 for (i = 0; i < ns; ++i)
916 if (r < weight[i] && ELEV == -INFINITY &&
918 ((!(capx[c] == sectx[c][i] &&
919 capy[c] == secty[c][i])) &&
920 (!(new_x(capx[c] + 2) == sectx[c][i] &&
921 capy[c] == secty[c][i]))))) {
928 /* Elevate land that is not mountain and not capital */
930 for (i = 0; i < ns; ++i)
931 dmoun[i] = distance_to_mountain();
932 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
933 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
935 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
938 for (i = 0; i < ns; ++i) {
939 if (ELEV != INFINITY &&
940 (c >= nc || ((!(capx[c] == sectx[c][i] &&
941 capy[c] == secty[c][i])) &&
942 (!(new_x(capx[c] + 2) == sectx[c][i] &&
943 capy[c] == secty[c][i]))))) {
944 h = 3 * (5 - dmoun[i]) + dsea[i];
954 if (newk >= HILLMIN && newk < PLATMIN)
958 elev[sectx[c][where]][secty[c][where]] = newk;
959 dsea[where] = -INFINITY;
960 dmoun[where] = INFINITY;
963 /* Elevate the mountains and capitals */
965 for (i = 0; i < ns; ++i) {
966 if (ELEV == INFINITY) {
968 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
970 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
971 rnd((256 - HIGHMIN) / 2);
972 } else if ((c < nc &&
973 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
974 ((new_x(capx[c] + 2) == sectx[c][i] &&
975 capy[c] == secty[c][i])))
981 #define distance_to_land() distance_to_what(x, y, 1)
988 for (y = 0; y < WORLD_Y; ++y) {
989 for (x = y % 2; x < WORLD_X; x += 2) {
990 if (elev[x][y] == -INFINITY)
991 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
996 /****************************************************************************
998 ****************************************************************************/
1005 fert = LANDMIN - e + 40;
1006 else if (e < FERT_MAX)
1007 fert = (120 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1018 oil = (LANDMIN - e) * 2 + rnd(2);
1019 else if (e <= OIL_MAX)
1020 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1030 if (e >= IRON_MIN && e < HIGHMIN)
1031 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1041 if (e >= GOLD_MIN) {
1043 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1045 gold = 100 - 20 * HIGHMIN / e;
1056 if (e >= URAN_MIN && e < HIGHMIN)
1057 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1064 add_resources(struct sctstr *sct)
1066 sct->sct_fertil = set_fert(sct->sct_elev);
1067 sct->sct_oil = set_oil(sct->sct_elev);
1068 sct->sct_min = set_iron(sct->sct_elev);
1069 sct->sct_gmin = set_gold(sct->sct_elev);
1070 sct->sct_uran = set_uran(sct->sct_elev);
1073 /****************************************************************************
1074 DESIGNATE THE SECTORS
1075 ****************************************************************************/
1083 /* sct = §s[0][0]; */
1085 for (y = 0; y < YSIZE; y++) {
1086 for (x = 0; x < XSIZE; x++) {
1087 fl_sct_init(x * 2 + (y & 1), y, sct);
1088 total = elev[sct->sct_x][y];
1089 if (total < LANDMIN) {
1090 sct->sct_type = SCT_WATER;
1091 } else if (total < HILLMIN)
1092 sct->sct_type = SCT_RURAL;
1093 else if (total < PLATMIN)
1094 sct->sct_type = SCT_MOUNT;
1095 else if (total < HIGHMIN)
1096 sct->sct_type = SCT_RURAL;
1098 sct->sct_type = SCT_MOUNT;
1099 sct->sct_elev = total;
1100 sct->sct_newtype = sct->sct_type;
1107 for (c = 0; c < nc; ++c) {
1108 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1109 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1111 set_coastal_flags();
1114 /****************************************************************************
1115 WRITE ALL THIS STUFF TO THE FILE
1116 ****************************************************************************/
1122 n = fwrite(sectsbuf, sizeof(struct sctstr), YSIZE * XSIZE, sect_fptr);
1124 perror(empfile[EF_SECTOR].file);
1127 if (n != YSIZE * XSIZE) {
1128 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1135 /****************************************************************************
1136 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1137 ****************************************************************************/
1143 for (i = 0; i < WORLD_Y; ++i) {
1147 for (j = i % 2; j < WORLD_X; j += 2) {
1148 if (own[j][i] == -1)
1151 printf("%c ", map_symbol(j, i));
1157 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");
1161 map_symbol(int x, int y)
1165 for (c = 0; c < nc; ++c)
1166 if ((x == capx[c] && y == capy[c])
1167 || (x == new_x(capx[c] + 2) && y == capy[c]))
1169 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1170 || elev[x][y] >= HIGHMIN)
1172 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1175 /***************************************************************************
1176 WRITE A SCRIPT FOR PLACING CAPITALS
1177 ****************************************************************************/
1179 write_newcap_script(void)
1182 FILE *script = fopen(outfile, "w");
1185 printf("fairland: error, unable to write to %s.\n", outfile);
1189 for (c = 0; c < nc; ++c) {
1190 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1192 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1193 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1195 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1198 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1204 qprint(const char * const fmt, ...)
1210 vfprintf(stdout, fmt, ap);
1216 fl_sct_init(coord x, coord y, struct sctstr *sp)
1218 sp->ef_type = EF_SECTOR;
1219 sp->sct_uid = XYOFFSET(x, y);
1224 sp->sct_coastal = 1;
1228 set_coastal_flags(void)
1232 qprint("setting coastal flags...\n");
1233 for (i = 0; i < nc; ++i)
1234 for (j = 0; j < sc; j++)
1235 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];
1236 for (i = nc; i < nc + ni; ++i)
1237 for (j = 0; j < isecs[i]; j++)
1238 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];