2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2007, 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 */
80 #include "prototypes.h"
85 /* do not change these 4 defines */
86 #define LANDMIN 1 /* plate altitude for normal land */
87 #define HILLMIN 34 /* plate altitude for hills */
88 #define PLATMIN 36 /* plate altitude for plateau */
89 #define HIGHMIN 98 /* plate altitude for mountains */
91 static void qprint(const char * const fmt, ...)
92 ATTRIBUTE((format (printf, 1, 2)));
94 #define DEFAULT_OUTFILE_NAME "newcap_script"
95 static const char *outfile = DEFAULT_OUTFILE_NAME;
96 /* mark the continents with a * so you can tell them
97 from the islands 1 = mark, 0 = don't mark. */
98 static int AIRPORT_MARKER = 0;
100 /* don't let the islands crash into each other.
101 1 = don't merge, 0 = merge. */
102 static int DISTINCT_ISLANDS = 1;
104 static char *program_name;
106 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
107 #define YSIZE (WORLD_Y)
108 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
109 #define INFINITY 999 /* a number which means "BIG" */
111 /* these defines prevent infinite loops:
114 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
115 when growing continents and islands */
116 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
117 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
118 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
123 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
124 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
125 #define rnd(x) (random() % (x))
127 int secs; /* number of sectors grown */
128 int ctot; /* total number of continents and islands grown */
129 int *isecs; /* array of how large each island is */
131 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
132 unsigned long rnd_seed; /* optional seed can be passed as an argument */
133 int *capx, *capy; /* location of the nc capitals */
134 int *mc, mcc; /* array and counter used for stability
135 check when perturbing */
136 int spike; /* are we spiking? */
137 int mind; /* the final distance between capitals that
139 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
140 int diry[] = { 0, -1, -1, 0, 1, 1 };
142 int **own; /* owner of the sector. -1 means water */
143 int **elev; /* elevation of the sectors */
144 int **sectx, **secty; /* the sectors for each continent */
145 int **sectc; /* which sectors are on the coast? */
146 int *vector; /* used for measuring distances */
147 int *weight; /* used for placing mountains */
148 int *dsea, *dmoun; /* the dist to the ocean and mountain */
149 FILE *sect_fptr; /* the file we write everything to */
150 struct sctstr **sects;
151 struct sctstr *sectsbuf;
152 int fl_status; /* is anything wrong? */
153 #define STATUS_NO_ROOM 1 /* there was no room to grow */
154 #define NUMTRIES 10 /* keep trying to grow this many times */
156 const char *numletter =
157 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
159 static void help(char *);
160 static void usage(void);
161 static void parse_args(int argc, char *argv[]);
162 static int allocate_memory(void);
163 static void init(void);
164 static int drift(void);
165 static void grow_continents(void);
166 static void create_elevations(void);
167 static void write_sects(void);
168 static int write_file(void);
169 static void output(void);
170 static int write_newcap_script(void);
171 static int stable(void);
172 static void elevate_land(void);
173 static void elevate_sea(void);
174 static int map_symbol(int x, int y);
175 static void fl_sct_init(coord, coord, struct sctstr *);
176 static void set_coastal_flags(void);
178 static void print_vars(void);
179 static void fl_move(int);
180 static void next_coast(int c, int x, int y, int *xp, int *yp);
181 static void grow_islands(void);
183 /****************************************************************************
185 ****************************************************************************/
188 main(int argc, char *argv[])
191 char *config_file = NULL;
194 program_name = argv[0];
195 rnd_seed = time(NULL);
197 while ((opt = getopt(argc, argv, "ae:hioqR:s:v")) != EOF) {
203 config_file = optarg;
206 DISTINCT_ISLANDS = 0;
215 rnd_seed = strtoul(optarg, NULL, 10);
224 printf("%s\n\n%s", version, legal);
232 if (emp_config(config_file))
235 parse_args(argc - optind, argv + optind);
236 if (allocate_memory() == -1)
243 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
244 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
245 qprint("seed is %lu\n", rnd_seed);
246 qprint("placing capitals...\n");
248 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
249 qprint("growing continents...\n");
251 } while (fl_status && ++i < NUMTRIES);
253 fputs("ERROR: World not large enough to hold continents\n",
257 qprint("growing islands:");
259 qprint("\nelevating land...\n");
261 qprint("designating sectors...\n");
263 qprint("adding resources...\n");
265 qprint("writing to sectors file...\n");
266 if (write_file() == -1)
269 write_newcap_script();
271 qprint("\t*** Resources have not been added ***\n");
280 puts("Creating a planet with:\n");
281 printf("%d continents\n", nc);
282 printf("continent size: %d\n", sc);
283 printf("number of islands: %d\n", ni);
284 printf("average size of islands: %d\n", is);
285 printf("spike: %d%%\n", sp);
286 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
287 pm, (pm * sc) / 100);
288 printf("minimum distance between continents: %d\n", di);
289 printf("minimum distance from islands to continents: %d\n", id);
290 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
298 for (i = 1; i * i < n * 10000; ++i) ;
299 return (i + 50) / 100;
302 /****************************************************************************
303 PARSE COMMAND LINE ARGUMENTS
304 ****************************************************************************/
307 help(char *complaint)
310 fprintf(stderr, "%s: %s\n", program_name, complaint);
311 fprintf(stderr, "Try -h for help.\n");
317 printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
318 " -a airport marker for continents\n"
319 " -e CONFIG-FILE configuration file\n"
321 " -h display this help and exit\n"
322 " -i islands may merge\n"
323 " -o don't set resources\n"
325 " -R SEED seed for random number generator\n"
326 " -s SCRIPT name of script to create (default %s)\n"
327 " NC number of continents\n"
328 " SC continent size\n"
329 " NI number of islands (default NC)\n"
330 " IS average island size (default SC/2)\n"
331 " SP spike percentage: 0 = round, 100 = snake (default %d)\n"
332 " PM percentage of land that is mountain (default %d)\n"
333 " DI minimum distance between continents (default %d)\n"
334 " ID minimum distance from islands to continents (default %d)\n",
335 program_name, dflt_econfig, DEFAULT_OUTFILE_NAME,
336 DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
340 parse_args(int argc, char *argv[])
343 help("missing arguments");
347 help("too many arguments");
352 puts("fairland: error -- number of continents must be > 0");
358 puts("fairland: error -- size of continents must be > 0");
386 pm = DEFAULT_MOUNTAIN;
393 di = DEFAULT_CONTDIST;
396 puts("fairland: error -- distance between continents must be >= 0");
399 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
400 puts("fairland: error -- distance between continents too large");
407 id = DEFAULT_ISLDIST;
409 puts("fairland: error -- distance from islands to continents must be >= 0");
412 if (id > WORLD_X || id > WORLD_Y) {
413 puts("fairland: error -- distance from islands to continents too large");
416 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
417 puts("fairland: error -- world not big enough to fit continents.");
418 puts("arguments must satisfy:");
419 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
424 /****************************************************************************
425 VARIABLE INITIALIZATION
426 ****************************************************************************/
429 allocate_memory(void)
434 fname = malloc(strlen(gamedir) + 1 + strlen(empfile[EF_SECTOR].file) + 1);
435 sprintf(fname, "%s/%s", gamedir, empfile[EF_SECTOR].file);
436 sect_fptr = fopen(fname, "wb");
437 if (sect_fptr == NULL) {
442 sectsbuf = calloc((YSIZE * XSIZE), sizeof(struct sctstr));
443 sects = calloc(YSIZE, sizeof(struct sctstr *));
444 for (i = 0; i < YSIZE; i++)
445 sects[i] = §sbuf[XSIZE * i];
446 capx = calloc(nc, sizeof(int));
447 capy = calloc(nc, sizeof(int));
448 vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
449 mc = calloc(STABLE_CYCLE, sizeof(int));
450 own = calloc(WORLD_X, sizeof(int *));
451 elev = calloc(WORLD_X, sizeof(int *));
452 for (i = 0; i < WORLD_X; ++i) {
453 own[i] = calloc(WORLD_Y, sizeof(int));
454 elev[i] = calloc(WORLD_Y, sizeof(int));
456 sectx = calloc(nc + ni, sizeof(int *));
457 secty = calloc(nc + ni, sizeof(int *));
458 sectc = calloc(nc + ni, sizeof(int *));
459 isecs = calloc(nc + ni, sizeof(int));
460 weight = calloc(MAX(sc, is * 2), sizeof(int));
461 dsea = calloc(MAX(sc, is * 2), sizeof(int));
462 dmoun = calloc(MAX(sc, is * 2), sizeof(int));
463 for (i = 0; i < nc; ++i) {
464 sectx[i] = calloc(sc, sizeof(int));
465 secty[i] = calloc(sc, sizeof(int));
466 sectc[i] = calloc(sc, sizeof(int));
468 for (i = nc; i < nc + ni; ++i) {
469 sectx[i] = calloc(is * 2, sizeof(int));
470 secty[i] = calloc(is * 2, sizeof(int));
471 sectc[i] = calloc(is * 2, sizeof(int));
480 int i, j, xx = 0, yy = 0;
485 for (i = 0; i < WORLD_X; ++i) {
486 for (j = 0; j < WORLD_Y; ++j) {
488 elev[i][j] = -INFINITY;
492 for (i = 0; i < nc; ++i, xx += 2) {
497 puts("fairland error: world not big enough for all the continents.\n");
504 for (i = 0; i < STABLE_CYCLE; ++i)
508 /****************************************************************************
509 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
510 ****************************************************************************/
512 /* How isolated is capital j?
515 iso(int j, int newx, int newy)
517 int i, md, d = WORLD_X + WORLD_Y;
519 for (i = 0; i < nc; ++i) {
522 md = mapdist(capx[i], capy[i], newx, newy);
530 /* Drift all the capitals
537 for (turns = 0; turns < DRIFT_MAX; ++turns) {
538 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
540 for (i = 0; i < nc; ++i)
546 /* Check to see if we have stabilized--can we stop drifting the capitals?
552 int i, isod, d = 0, stab = 1;
554 for (i = 0; i < nc; ++i) {
555 isod = iso(i, capx[i], capy[i]);
559 for (i = 0; i < STABLE_CYCLE; ++i)
563 mcc = (mcc + 1) % STABLE_CYCLE;
567 /* This routine does the actual drifting
573 int i, n, newx, newy;
575 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
576 newx = new_x(capx[j] + dirx[i]);
577 newy = new_y(capy[j] + diry[i]);
578 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
586 /****************************************************************************
588 ****************************************************************************/
590 /* Look for a coastal sector of continent c
598 for (i = 0; i < secs; ++i) {
600 for (j = 0; j < 6; ++j)
601 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
606 /* Used for measuring distances
618 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
621 return i > 1 || vector[0] > 0;
624 /* Test to see if we're allowed to grow there: the arguments di and id
627 try_to_grow(int c, int newx, int newy, int d)
631 for (i = 1; i <= d; ++i) {
632 for (j = 0; j < i; ++j)
637 for (j = 0; j < i; ++j) {
638 px = new_x(px + dirx[vector[j]]);
639 py = new_y(py + diry[vector[j]]);
641 if (own[px][py] != -1 &&
643 (DISTINCT_ISLANDS || own[px][py] < nc))
645 } while (next_vector(i));
647 sectx[c][secs] = newx;
648 secty[c][secs] = newy;
653 /* Move along the coast in a clockwise direction.
657 next_coast(int c, int x, int y, int *xp, int *yp)
659 int i, nx, ny, wat = 0;
667 for (i = 0; i < 12; ++i) {
668 nx = new_x(x + dirx[i % 6]);
669 ny = new_y(y + diry[i % 6]);
670 if (own[nx][ny] == -1)
672 if (wat && own[nx][ny] == c) {
680 /* Choose a sector to grow from
692 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
697 } while (i != starti);
699 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
708 /* Grow continent c by 1 sector
712 grow_one_sector(int c)
714 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
716 spike = rnd(100) < sp;
717 if ((try1 = new_try(c)) == -1)
719 x = sx = sectx[c][try1];
720 y = sy = secty[c][try1];
725 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
726 newx = new_x(x + dirx[i]);
727 newy = new_y(y + diry[i]);
728 if (own[newx][newy] == -1 &&
730 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
731 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
732 if (try_to_grow(c, newx, newy, c < nc ? di : id))
736 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
737 newx = new_x(x + dirx[i]);
738 newy = new_y(y + diry[i]);
739 if (own[newx][newy] == -1)
740 if (try_to_grow(c, newx, newy, c < nc ? di : id))
743 next_coast(c, x, y, &x, &y);
745 } while (!done && coast_search < COAST_SEARCH_MAX &&
746 (secs == 1 || x != sx || y != sy));
747 if (!done && c < nc) {
748 qprint("fairland: error -- continent %c had no room to grow!\n",
750 fl_status |= STATUS_NO_ROOM;
755 /* Grow all the continents
758 grow_continents(void)
762 for (c = 0; c < nc; ++c) {
763 sectx[c][0] = capx[c];
764 secty[c][0] = capy[c];
765 own[sectx[c][0]][secty[c][0]] = c;
766 sectx[c][1] = new_x(capx[c] + 2);
767 secty[c][1] = capy[c];
768 own[sectx[c][1]][secty[c][1]] = c;
771 for (secs = 2; secs < sc && !fl_status; ++secs) {
772 for (c = 0; c < nc; ++c) {
777 for (c = 0; c < nc; ++c)
781 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
785 /****************************************************************************
787 ****************************************************************************/
789 /* Choose a place to start growing an island from
792 place_island(int c, int *xp, int *yp)
795 int ssy = rnd(WORLD_Y);
796 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
798 if (ssx > WORLD_X - 2)
799 ssx = new_x(ssx + 2);
800 for (d = di + id; d >= id; --d) {
804 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
805 if (*xp >= WORLD_X) {
806 *yp = new_y(*yp + 1);
808 if (*xp == sx && *yp == sy)
811 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
818 /* Grow all the islands
826 for (c = nc; c < nc + ni; ++c) {
828 if (!place_island(c, &x, &y))
830 isiz = 1 + rnd(2 * is - 1);
834 } while (secs < isiz && grow_one_sector(c));
836 qprint(" %d(%d)", c - nc + 1, secs);
842 /****************************************************************************
844 ****************************************************************************/
846 create_elevations(void)
852 /* Generic function for finding the distance to the closest sea, land, or
856 distance_to_what(int x, int y, int flag)
860 for (d = 1; d < 5; ++d) {
861 for (j = 0; j < d; ++j)
866 for (j = 0; j < d; ++j) {
867 px = new_x(px + dirx[vector[j]]);
868 py = new_y(py + diry[vector[j]]);
871 case 0: /* distance to sea */
872 if (own[px][py] == -1)
875 case 1: /* distance to land */
876 if (own[px][py] != -1)
879 case 2: /* distance to mountain */
880 if (elev[px][py] == INFINITY)
884 } while (next_vector(d));
889 #define ELEV elev[sectx[c][i]][secty[c][i]]
890 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
891 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
893 /* Decide where the mountains go
898 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
901 for (c = 0; c < ctot; ++c) {
903 ns = (c < nc) ? sc : isecs[c];
904 nm = (pm * ns) / 100;
906 /* Place the mountains */
908 for (i = 0; i < ns; ++i) {
909 dsea[i] = distance_to_sea();
910 weight[i] = (total += (dsea[i] * dsea[i]));
913 for (k = nm, mountain_search = 0;
914 k && mountain_search < MOUNTAIN_SEARCH_MAX;
917 for (i = 0; i < ns; ++i)
918 if (r < weight[i] && ELEV == -INFINITY &&
920 ((!(capx[c] == sectx[c][i] &&
921 capy[c] == secty[c][i])) &&
922 (!(new_x(capx[c] + 2) == sectx[c][i] &&
923 capy[c] == secty[c][i]))))) {
930 /* Elevate land that is not mountain and not capital */
932 for (i = 0; i < ns; ++i)
933 dmoun[i] = distance_to_mountain();
934 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
935 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
937 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
940 for (i = 0; i < ns; ++i) {
941 if (ELEV != INFINITY &&
942 (c >= nc || ((!(capx[c] == sectx[c][i] &&
943 capy[c] == secty[c][i])) &&
944 (!(new_x(capx[c] + 2) == sectx[c][i] &&
945 capy[c] == secty[c][i]))))) {
946 h = 3 * (5 - dmoun[i]) + dsea[i];
956 if (newk >= HILLMIN && newk < PLATMIN)
960 elev[sectx[c][where]][secty[c][where]] = newk;
961 dsea[where] = -INFINITY;
962 dmoun[where] = INFINITY;
965 /* Elevate the mountains and capitals */
967 for (i = 0; i < ns; ++i) {
968 if (ELEV == INFINITY) {
970 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
972 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
973 rnd((256 - HIGHMIN) / 2);
974 } else if ((c < nc &&
975 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
976 ((new_x(capx[c] + 2) == sectx[c][i] &&
977 capy[c] == secty[c][i])))
983 #define distance_to_land() distance_to_what(x, y, 1)
990 for (y = 0; y < WORLD_Y; ++y) {
991 for (x = y % 2; x < WORLD_X; x += 2) {
992 if (elev[x][y] == -INFINITY)
993 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
998 /****************************************************************************
1000 ****************************************************************************/
1007 fert = LANDMIN - e + 40;
1008 else if (e < FERT_MAX)
1009 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1020 oil = (LANDMIN - e) * 2 + rnd(2);
1021 else if (e <= OIL_MAX)
1022 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1032 if (e >= IRON_MIN && e < HIGHMIN)
1033 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1043 if (e >= GOLD_MIN) {
1045 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1047 gold = 100 - 20 * HIGHMIN / e;
1058 if (e >= URAN_MIN && e < HIGHMIN)
1059 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1066 add_resources(struct sctstr *sct)
1068 sct->sct_fertil = set_fert(sct->sct_elev);
1069 sct->sct_oil = set_oil(sct->sct_elev);
1070 sct->sct_min = set_iron(sct->sct_elev);
1071 sct->sct_gmin = set_gold(sct->sct_elev);
1072 sct->sct_uran = set_uran(sct->sct_elev);
1075 /****************************************************************************
1076 DESIGNATE THE SECTORS
1077 ****************************************************************************/
1085 /* sct = §s[0][0]; */
1087 for (y = 0; y < YSIZE; y++) {
1088 for (x = 0; x < XSIZE; x++, sct++) {
1089 fl_sct_init(x * 2 + (y & 1), y, sct);
1090 total = elev[sct->sct_x][y];
1091 if (total < LANDMIN) {
1092 sct->sct_type = SCT_WATER;
1093 } else if (total < HILLMIN)
1094 sct->sct_type = SCT_RURAL;
1095 else if (total < PLATMIN)
1096 sct->sct_type = SCT_MOUNT;
1097 else if (total < HIGHMIN)
1098 sct->sct_type = SCT_RURAL;
1100 sct->sct_type = SCT_MOUNT;
1101 sct->sct_elev = total;
1102 sct->sct_newtype = sct->sct_type;
1108 for (c = 0; c < nc; ++c) {
1109 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1110 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1112 set_coastal_flags();
1115 /****************************************************************************
1116 WRITE ALL THIS STUFF TO THE FILE
1117 ****************************************************************************/
1123 n = fwrite(sectsbuf, sizeof(struct sctstr), YSIZE * XSIZE, sect_fptr);
1125 perror(empfile[EF_SECTOR].file);
1128 if (n != YSIZE * XSIZE) {
1129 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1136 /****************************************************************************
1137 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1138 ****************************************************************************/
1144 for (i = 0; i < WORLD_Y; ++i) {
1148 for (j = i % 2; j < WORLD_X; j += 2) {
1149 if (own[j][i] == -1)
1152 printf("%c ", map_symbol(j, i));
1158 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");
1162 map_symbol(int x, int y)
1166 for (c = 0; c < nc; ++c)
1167 if ((x == capx[c] && y == capy[c])
1168 || (x == new_x(capx[c] + 2) && y == capy[c]))
1170 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1171 || elev[x][y] >= HIGHMIN)
1173 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1176 /***************************************************************************
1177 WRITE A SCRIPT FOR PLACING CAPITALS
1178 ****************************************************************************/
1180 write_newcap_script(void)
1183 FILE *script = fopen(outfile, "w");
1186 printf("fairland: error, unable to write to %s.\n", outfile);
1190 for (c = 0; c < nc; ++c) {
1191 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1193 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1194 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1196 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1199 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1205 qprint(const char * const fmt, ...)
1211 vfprintf(stdout, fmt, ap);
1217 fl_sct_init(coord x, coord y, struct sctstr *sp)
1219 sp->ef_type = EF_SECTOR;
1226 sp->sct_defense = 0;
1227 sp->sct_coastal = 1;
1231 set_coastal_flags(void)
1235 qprint("setting coastal flags...\n");
1236 for (i = 0; i < nc; ++i)
1237 for (j = 0; j < sc; j++)
1238 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];
1239 for (i = nc; i < nc + ni; ++i)
1240 for (j = 0; j < isecs[i]; j++)
1241 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];