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 */
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, xx += 2) {
494 puts("fairland error: world not big enough for all the continents.\n");
501 for (i = 0; i < STABLE_CYCLE; ++i)
505 /****************************************************************************
506 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
507 ****************************************************************************/
509 /* How isolated is capital j?
512 iso(int j, int newx, int newy)
514 int i, md, d = WORLD_X + WORLD_Y;
516 for (i = 0; i < nc; ++i) {
519 md = mapdist(capx[i], capy[i], newx, newy);
527 /* Drift all the capitals
534 for (turns = 0; turns < DRIFT_MAX; ++turns) {
535 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
537 for (i = 0; i < nc; ++i)
543 /* Check to see if we have stabilized--can we stop drifting the capitals?
549 int i, isod, d = 0, stab = 1;
551 for (i = 0; i < nc; ++i) {
552 isod = iso(i, capx[i], capy[i]);
556 for (i = 0; i < STABLE_CYCLE; ++i)
560 mcc = (mcc + 1) % STABLE_CYCLE;
564 /* This routine does the actual drifting
570 int i, n, newx, newy;
572 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
573 newx = new_x(capx[j] + dirx[i]);
574 newy = new_y(capy[j] + diry[i]);
575 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
583 /****************************************************************************
585 ****************************************************************************/
587 /* Look for a coastal sector of continent c
595 for (i = 0; i < secs; ++i) {
597 for (j = 0; j < 6; ++j)
598 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
603 /* Used for measuring distances
615 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
618 return i > 1 || vector[0] > 0;
621 /* Test to see if we're allowed to grow there: the arguments di and id
624 try_to_grow(int c, int newx, int newy, int d)
628 for (i = 1; i <= d; ++i) {
629 for (j = 0; j < i; ++j)
634 for (j = 0; j < i; ++j) {
635 px = new_x(px + dirx[vector[j]]);
636 py = new_y(py + diry[vector[j]]);
638 if (own[px][py] != -1 &&
640 (DISTINCT_ISLANDS || own[px][py] < nc))
642 } while (next_vector(i));
644 sectx[c][secs] = newx;
645 secty[c][secs] = newy;
650 /* Move along the coast in a clockwise direction.
654 next_coast(int c, int x, int y, int *xp, int *yp)
656 int i, nx, ny, wat = 0;
664 for (i = 0; i < 12; ++i) {
665 nx = new_x(x + dirx[i % 6]);
666 ny = new_y(y + diry[i % 6]);
667 if (own[nx][ny] == -1)
669 if (wat && own[nx][ny] == c) {
677 /* Choose a sector to grow from
689 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
694 } while (i != starti);
696 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
705 /* Grow continent c by 1 sector
709 grow_one_sector(int c)
711 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
713 spike = rnd(100) < sp;
714 if ((try1 = new_try(c)) == -1)
716 x = sx = sectx[c][try1];
717 y = sy = secty[c][try1];
722 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
723 newx = new_x(x + dirx[i]);
724 newy = new_y(y + diry[i]);
725 if (own[newx][newy] == -1 &&
727 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
728 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
729 if (try_to_grow(c, newx, newy, c < nc ? di : id))
733 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
734 newx = new_x(x + dirx[i]);
735 newy = new_y(y + diry[i]);
736 if (own[newx][newy] == -1)
737 if (try_to_grow(c, newx, newy, c < nc ? di : id))
740 next_coast(c, x, y, &x, &y);
742 } while (!done && coast_search < COAST_SEARCH_MAX &&
743 (secs == 1 || x != sx || y != sy));
744 if (!done && c < nc) {
745 qprint("fairland: error -- continent %c had no room to grow!\n",
747 fl_status |= STATUS_NO_ROOM;
752 /* Grow all the continents
755 grow_continents(void)
759 for (c = 0; c < nc; ++c) {
760 sectx[c][0] = capx[c];
761 secty[c][0] = capy[c];
762 own[sectx[c][0]][secty[c][0]] = c;
763 sectx[c][1] = new_x(capx[c] + 2);
764 secty[c][1] = capy[c];
765 own[sectx[c][1]][secty[c][1]] = c;
768 for (secs = 2; secs < sc && !fl_status; ++secs) {
769 for (c = 0; c < nc; ++c) {
774 for (c = 0; c < nc; ++c)
778 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
782 /****************************************************************************
784 ****************************************************************************/
786 /* Choose a place to start growing an island from
789 place_island(int c, int *xp, int *yp)
792 int ssy = rnd(WORLD_Y);
793 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
795 if (ssx > WORLD_X - 2)
796 ssx = new_x(ssx + 2);
797 for (d = di + id; d >= id; --d) {
801 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
802 if (*xp >= WORLD_X) {
803 *yp = new_y(*yp + 1);
805 if (*xp == sx && *yp == sy)
808 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
815 /* Grow all the islands
823 for (c = nc; c < nc + ni; ++c) {
825 if (!place_island(c, &x, &y))
827 isiz = 1 + rnd(2 * is - 1);
831 } while (secs < isiz && grow_one_sector(c));
833 qprint(" %d(%d)", c - nc + 1, secs);
839 /****************************************************************************
841 ****************************************************************************/
843 create_elevations(void)
849 /* Generic function for finding the distance to the closest sea, land, or
853 distance_to_what(int x, int y, int flag)
857 for (d = 1; d < 5; ++d) {
858 for (j = 0; j < d; ++j)
863 for (j = 0; j < d; ++j) {
864 px = new_x(px + dirx[vector[j]]);
865 py = new_y(py + diry[vector[j]]);
868 case 0: /* distance to sea */
869 if (own[px][py] == -1)
872 case 1: /* distance to land */
873 if (own[px][py] != -1)
876 case 2: /* distance to mountain */
877 if (elev[px][py] == INFINITY)
881 } while (next_vector(d));
886 #define ELEV elev[sectx[c][i]][secty[c][i]]
887 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
888 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
890 /* Decide where the mountains go
895 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
898 for (c = 0; c < ctot; ++c) {
900 ns = (c < nc) ? sc : isecs[c];
901 nm = (pm * ns) / 100;
903 /* Place the mountains */
905 for (i = 0; i < ns; ++i) {
906 dsea[i] = distance_to_sea();
907 weight[i] = (total += (dsea[i] * dsea[i]));
910 for (k = nm, mountain_search = 0;
911 k && mountain_search < MOUNTAIN_SEARCH_MAX;
914 for (i = 0; i < ns; ++i)
915 if (r < weight[i] && ELEV == -INFINITY &&
917 ((!(capx[c] == sectx[c][i] &&
918 capy[c] == secty[c][i])) &&
919 (!(new_x(capx[c] + 2) == sectx[c][i] &&
920 capy[c] == secty[c][i]))))) {
927 /* Elevate land that is not mountain and not capital */
929 for (i = 0; i < ns; ++i)
930 dmoun[i] = distance_to_mountain();
931 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
932 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
934 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
937 for (i = 0; i < ns; ++i) {
938 if (ELEV != INFINITY &&
939 (c >= nc || ((!(capx[c] == sectx[c][i] &&
940 capy[c] == secty[c][i])) &&
941 (!(new_x(capx[c] + 2) == sectx[c][i] &&
942 capy[c] == secty[c][i]))))) {
943 h = 3 * (5 - dmoun[i]) + dsea[i];
953 if (newk >= HILLMIN && newk < PLATMIN)
957 elev[sectx[c][where]][secty[c][where]] = newk;
958 dsea[where] = -INFINITY;
959 dmoun[where] = INFINITY;
962 /* Elevate the mountains and capitals */
964 for (i = 0; i < ns; ++i) {
965 if (ELEV == INFINITY) {
967 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
969 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
970 rnd((256 - HIGHMIN) / 2);
971 } else if ((c < nc &&
972 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
973 ((new_x(capx[c] + 2) == sectx[c][i] &&
974 capy[c] == secty[c][i])))
980 #define distance_to_land() distance_to_what(x, y, 1)
987 for (y = 0; y < WORLD_Y; ++y) {
988 for (x = y % 2; x < WORLD_X; x += 2) {
989 if (elev[x][y] == -INFINITY)
990 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
995 /****************************************************************************
997 ****************************************************************************/
1004 fert = LANDMIN - e + 40;
1005 else if (e < FERT_MAX)
1006 fert = (120 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1017 oil = (LANDMIN - e) * 2 + rnd(2);
1018 else if (e <= OIL_MAX)
1019 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1029 if (e >= IRON_MIN && e < HIGHMIN)
1030 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1040 if (e >= GOLD_MIN) {
1042 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1044 gold = 100 - 20 * HIGHMIN / e;
1055 if (e >= URAN_MIN && e < HIGHMIN)
1056 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1063 add_resources(struct sctstr *sct)
1065 sct->sct_fertil = set_fert(sct->sct_elev);
1066 sct->sct_oil = set_oil(sct->sct_elev);
1067 sct->sct_min = set_iron(sct->sct_elev);
1068 sct->sct_gmin = set_gold(sct->sct_elev);
1069 sct->sct_uran = set_uran(sct->sct_elev);
1072 /****************************************************************************
1073 DESIGNATE THE SECTORS
1074 ****************************************************************************/
1082 /* sct = §s[0][0]; */
1084 for (y = 0; y < YSIZE; y++) {
1085 for (x = 0; x < XSIZE; x++, sct++) {
1086 fl_sct_init(x * 2 + (y & 1), y, sct);
1087 total = elev[sct->sct_x][y];
1088 if (total < LANDMIN) {
1089 sct->sct_type = SCT_WATER;
1090 } else if (total < HILLMIN)
1091 sct->sct_type = SCT_RURAL;
1092 else if (total < PLATMIN)
1093 sct->sct_type = SCT_MOUNT;
1094 else if (total < HIGHMIN)
1095 sct->sct_type = SCT_RURAL;
1097 sct->sct_type = SCT_MOUNT;
1098 sct->sct_elev = total;
1099 sct->sct_newtype = sct->sct_type;
1105 for (c = 0; c < nc; ++c) {
1106 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1107 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1109 set_coastal_flags();
1112 /****************************************************************************
1113 WRITE ALL THIS STUFF TO THE FILE
1114 ****************************************************************************/
1120 n = fwrite(sectsbuf, sizeof(struct sctstr), YSIZE * XSIZE, sect_fptr);
1122 perror(empfile[EF_SECTOR].file);
1125 if (n != YSIZE * XSIZE) {
1126 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1133 /****************************************************************************
1134 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1135 ****************************************************************************/
1141 for (i = 0; i < WORLD_Y; ++i) {
1145 for (j = i % 2; j < WORLD_X; j += 2) {
1146 if (own[j][i] == -1)
1149 printf("%c ", map_symbol(j, i));
1155 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");
1159 map_symbol(int x, int y)
1163 for (c = 0; c < nc; ++c)
1164 if ((x == capx[c] && y == capy[c])
1165 || (x == new_x(capx[c] + 2) && y == capy[c]))
1167 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1168 || elev[x][y] >= HIGHMIN)
1170 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1173 /***************************************************************************
1174 WRITE A SCRIPT FOR PLACING CAPITALS
1175 ****************************************************************************/
1177 write_newcap_script(void)
1180 FILE *script = fopen(outfile, "w");
1183 printf("fairland: error, unable to write to %s.\n", outfile);
1187 for (c = 0; c < nc; ++c) {
1188 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1190 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1191 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1193 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1196 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1202 qprint(const char * const fmt, ...)
1208 vfprintf(stdout, fmt, ap);
1214 fl_sct_init(coord x, coord y, struct sctstr *sp)
1216 sp->ef_type = EF_SECTOR;
1223 sp->sct_defense = 0;
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];