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 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 */
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)
127 #define rnd(x) (random() % (x))
129 int secs; /* number of sectors grown */
130 int ctot; /* total number of continents and islands grown */
131 int *isecs; /* array of how large each island is */
133 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
134 unsigned long rnd_seed; /* optional seed can be passed as an argument */
135 int *capx, *capy; /* location of the nc capitals */
136 int *mc, mcc; /* array and counter used for stability
137 check when perturbing */
138 int spike; /* are we spiking? */
139 int mind; /* the final distance between capitals that
141 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
142 int diry[] = { 0, -1, -1, 0, 1, 1 };
144 int **own; /* owner of the sector. -1 means water */
145 int **elev; /* elevation of the sectors */
146 int **sectx, **secty; /* the sectors for each continent */
147 int **sectc; /* which sectors are on the coast? */
148 int *vector; /* used for measuring distances */
149 int *weight; /* used for placing mountains */
150 int *dsea, *dmoun; /* the dist to the ocean and mountain */
151 FILE *sect_fptr; /* the file we write everything to */
152 struct sctstr **sects;
153 struct sctstr *sectsbuf;
154 int fl_status; /* is anything wrong? */
155 #define STATUS_NO_ROOM 1 /* there was no room to grow */
156 #define NUMTRIES 10 /* keep trying to grow this many times */
158 const char *numletter =
159 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
161 static void help(char *);
162 static void usage(void);
163 static void parse_args(int argc, char *argv[]);
164 static int allocate_memory(void);
165 static void init(void);
166 static int drift(void);
167 static void grow_continents(void);
168 static void create_elevations(void);
169 static void write_sects(void);
170 static int write_file(void);
171 static void output(void);
172 static int write_newcap_script(void);
173 static int stable(void);
174 static void elevate_land(void);
175 static void elevate_sea(void);
176 static int map_symbol(int x, int y);
177 static void fl_sct_init(coord x, coord y, s_char *ptr,
179 static void set_coastal_flags(void);
181 static void print_vars(void);
182 static void fl_move(int);
183 static void next_coast(int c, int x, int y, int *xp, int *yp);
184 static void grow_islands(void);
186 /****************************************************************************
188 ****************************************************************************/
191 main(int argc, char *argv[])
194 char *config_file = NULL;
197 program_name = argv[0];
198 rnd_seed = time(NULL);
200 while ((opt = getopt(argc, argv, "ae:hioqs:R:")) != EOF) {
206 DISTINCT_ISLANDS = 0;
209 config_file = optarg;
221 rnd_seed = strtoul(optarg, NULL, 10);
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 [-e CONFIG] [-aiqo] [-s SCRIPT] [-R SEED] NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
319 " -o don't set resources\n"
320 " -a airport marker for continents\n"
321 " -i islands may merge\n"
322 " -R SEED seed for random number generator\n"
323 " -e CONFIG configuration file\n"
324 " -s SCRIPT name of script to create (default %s)\n"
325 " NC number of continents\n"
326 " SC continent size\n"
327 " NI number of islands (default NC)\n"
328 " IS average island size (default SC/2)\n"
329 " SP spike percentage: 0 = round, 100 = snake\n"
331 " PM percentage of land that is mountain (default %d)\n"
332 " DI minimum distance between continents (default %d)\n"
333 " ID minimum distance from islands to continents (default %d)\n",
334 program_name, DEFAULT_OUTFILE_NAME,
335 DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
339 parse_args(int argc, char *argv[])
342 help("missing arguments");
346 help("too many arguments");
351 puts("fairland: error -- number of continents must be > 0");
357 puts("fairland: error -- size of continents must be > 0");
385 pm = DEFAULT_MOUNTAIN;
392 di = DEFAULT_CONTDIST;
395 puts("fairland: error -- distance between continents must be >= 0");
398 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
399 puts("fairland: error -- distance between continents too large");
406 id = DEFAULT_ISLDIST;
408 puts("fairland: error -- distance from islands to continents must be >= 0");
411 if (id > WORLD_X || id > WORLD_Y) {
412 puts("fairland: error -- distance from islands to continents too large");
415 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
416 puts("fairland: error -- world not big enough to fit continents.");
417 puts("arguments must satisfy:");
418 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
423 /****************************************************************************
424 VARIABLE INITIALIZATION
425 ****************************************************************************/
428 allocate_memory(void)
433 fname = malloc(strlen(datadir) + 1 + strlen(empfile[EF_SECTOR].file) + 1);
434 sprintf(fname, "%s/%s", datadir, empfile[EF_SECTOR].file);
435 sect_fptr = fopen(fname, "wb");
436 if (sect_fptr == NULL) {
441 sectsbuf = calloc((YSIZE * XSIZE), sizeof(struct sctstr));
442 sects = calloc(YSIZE, sizeof(struct sctstr *));
443 for (i = 0; i < YSIZE; i++)
444 sects[i] = §sbuf[XSIZE * i];
445 capx = calloc(nc, sizeof(int));
446 capy = calloc(nc, sizeof(int));
447 vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
448 mc = calloc(STABLE_CYCLE, sizeof(int));
449 own = calloc(WORLD_X, sizeof(int *));
450 elev = calloc(WORLD_X, sizeof(int *));
451 for (i = 0; i < WORLD_X; ++i) {
452 own[i] = calloc(WORLD_Y, sizeof(int));
453 elev[i] = calloc(WORLD_Y, sizeof(int));
455 sectx = calloc(nc + ni, sizeof(int *));
456 secty = calloc(nc + ni, sizeof(int *));
457 sectc = calloc(nc + ni, sizeof(int *));
458 isecs = calloc(nc + ni, sizeof(int));
459 weight = calloc(MAX(sc, is * 2), sizeof(int));
460 dsea = calloc(MAX(sc, is * 2), sizeof(int));
461 dmoun = calloc(MAX(sc, is * 2), sizeof(int));
462 for (i = 0; i < nc; ++i) {
463 sectx[i] = calloc(sc, sizeof(int));
464 secty[i] = calloc(sc, sizeof(int));
465 sectc[i] = calloc(sc, sizeof(int));
467 for (i = nc; i < nc + ni; ++i) {
468 sectx[i] = calloc(is * 2, sizeof(int));
469 secty[i] = calloc(is * 2, sizeof(int));
470 sectc[i] = calloc(is * 2, sizeof(int));
479 int i, j, xx = 0, yy = 0;
484 for (i = 0; i < WORLD_X; ++i) {
485 for (j = 0; j < WORLD_Y; ++j) {
487 elev[i][j] = -INFINITY;
491 for (i = 0; i < nc; ++i, xx += 2) {
496 puts("fairland error: world not big enough for all the continents.\n");
503 for (i = 0; i < STABLE_CYCLE; ++i)
507 /****************************************************************************
508 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
509 ****************************************************************************/
511 /* How isolated is capital j?
514 iso(int j, int newx, int newy)
516 int i, md, d = WORLD_X + WORLD_Y;
518 for (i = 0; i < nc; ++i) {
521 md = mapdist(capx[i], capy[i], newx, newy);
529 /* Drift all the capitals
536 for (turns = 0; turns < DRIFT_MAX; ++turns) {
537 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
539 for (i = 0; i < nc; ++i)
545 /* Check to see if we have stabilized--can we stop drifting the capitals?
551 int i, isod, d = 0, stab = 1;
553 for (i = 0; i < nc; ++i) {
554 isod = iso(i, capx[i], capy[i]);
558 for (i = 0; i < STABLE_CYCLE; ++i)
562 mcc = (mcc + 1) % STABLE_CYCLE;
566 /* This routine does the actual drifting
572 int i, n, newx, newy;
574 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
575 newx = new_x(capx[j] + dirx[i]);
576 newy = new_y(capy[j] + diry[i]);
577 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
585 /****************************************************************************
587 ****************************************************************************/
589 /* Look for a coastal sector of continent c
597 for (i = 0; i < secs; ++i) {
599 for (j = 0; j < 6; ++j)
600 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
605 /* Used for measuring distances
617 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
620 return i > 1 || vector[0] > 0;
623 /* Test to see if we're allowed to grow there: the arguments di and id
626 try_to_grow(int c, int newx, int newy, int d)
630 for (i = 1; i <= d; ++i) {
631 for (j = 0; j < i; ++j)
636 for (j = 0; j < i; ++j) {
637 px = new_x(px + dirx[vector[j]]);
638 py = new_y(py + diry[vector[j]]);
640 if (own[px][py] != -1 &&
642 (DISTINCT_ISLANDS || own[px][py] < nc))
644 } while (next_vector(i));
646 sectx[c][secs] = newx;
647 secty[c][secs] = newy;
652 /* Move along the coast in a clockwise direction.
656 next_coast(int c, int x, int y, int *xp, int *yp)
658 int i, nx, ny, wat = 0;
666 for (i = 0; i < 12; ++i) {
667 nx = new_x(x + dirx[i % 6]);
668 ny = new_y(y + diry[i % 6]);
669 if (own[nx][ny] == -1)
671 if (wat && own[nx][ny] == c) {
679 /* Choose a sector to grow from
691 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
696 } while (i != starti);
698 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
707 /* Grow continent c by 1 sector
711 grow_one_sector(int c)
713 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
715 spike = rnd(100) < sp;
716 if ((try1 = new_try(c)) == -1)
718 x = sx = sectx[c][try1];
719 y = sy = secty[c][try1];
724 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
725 newx = new_x(x + dirx[i]);
726 newy = new_y(y + diry[i]);
727 if (own[newx][newy] == -1 &&
729 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
730 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
731 if (try_to_grow(c, newx, newy, c < nc ? di : id))
735 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
736 newx = new_x(x + dirx[i]);
737 newy = new_y(y + diry[i]);
738 if (own[newx][newy] == -1)
739 if (try_to_grow(c, newx, newy, c < nc ? di : id))
742 next_coast(c, x, y, &x, &y);
744 } while (!done && coast_search < COAST_SEARCH_MAX &&
745 (secs == 1 || x != sx || y != sy));
746 if (!done && c < nc) {
747 qprint("fairland: error -- continent %c had no room to grow!\n",
749 fl_status |= STATUS_NO_ROOM;
754 /* Grow all the continents
757 grow_continents(void)
761 for (c = 0; c < nc; ++c) {
762 sectx[c][0] = capx[c];
763 secty[c][0] = capy[c];
764 own[sectx[c][0]][secty[c][0]] = c;
765 sectx[c][1] = new_x(capx[c] + 2);
766 secty[c][1] = capy[c];
767 own[sectx[c][1]][secty[c][1]] = c;
770 for (secs = 2; secs < sc && !fl_status; ++secs) {
771 for (c = 0; c < nc; ++c) {
776 for (c = 0; c < nc; ++c)
780 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
784 /****************************************************************************
786 ****************************************************************************/
788 /* Choose a place to start growing an island from
791 place_island(int c, int *xp, int *yp)
794 int ssy = rnd(WORLD_Y);
795 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
797 if (ssx > WORLD_X - 2)
798 ssx = new_x(ssx + 2);
799 for (d = di + id; d >= id; --d) {
803 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
804 if (*xp >= WORLD_X) {
805 *yp = new_y(*yp + 1);
807 if (*xp == sx && *yp == sy)
810 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
817 /* Grow all the islands
825 for (c = nc; c < nc + ni; ++c) {
827 if (!place_island(c, &x, &y))
829 isiz = 1 + rnd(2 * is - 1);
833 } while (secs < isiz && grow_one_sector(c));
835 qprint(" %d(%d)", c - nc + 1, secs);
841 /****************************************************************************
843 ****************************************************************************/
845 create_elevations(void)
851 /* Generic function for finding the distance to the closest sea, land, or
855 distance_to_what(int x, int y, int flag)
859 for (d = 1; d < 5; ++d) {
860 for (j = 0; j < d; ++j)
865 for (j = 0; j < d; ++j) {
866 px = new_x(px + dirx[vector[j]]);
867 py = new_y(py + diry[vector[j]]);
870 case 0: /* distance to sea */
871 if (own[px][py] == -1)
874 case 1: /* distance to land */
875 if (own[px][py] != -1)
878 case 2: /* distance to mountain */
879 if (elev[px][py] == INFINITY)
883 } while (next_vector(d));
888 #define ELEV elev[sectx[c][i]][secty[c][i]]
889 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
890 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
892 /* Decide where the mountains go
897 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
900 for (c = 0; c < ctot; ++c) {
902 ns = (c < nc) ? sc : isecs[c];
903 nm = (pm * ns) / 100;
905 /* Place the mountains */
907 for (i = 0; i < ns; ++i) {
908 dsea[i] = distance_to_sea();
909 weight[i] = (total += (dsea[i] * dsea[i]));
912 for (k = nm, mountain_search = 0;
913 k && mountain_search < MOUNTAIN_SEARCH_MAX;
916 for (i = 0; i < ns; ++i)
917 if (r < weight[i] && ELEV == -INFINITY &&
919 ((!(capx[c] == sectx[c][i] &&
920 capy[c] == secty[c][i])) &&
921 (!(new_x(capx[c] + 2) == sectx[c][i] &&
922 capy[c] == secty[c][i]))))) {
929 /* Elevate land that is not mountain and not capital */
931 for (i = 0; i < ns; ++i)
932 dmoun[i] = distance_to_mountain();
933 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
934 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
936 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
939 for (i = 0; i < ns; ++i) {
940 if (ELEV != INFINITY &&
941 (c >= nc || ((!(capx[c] == sectx[c][i] &&
942 capy[c] == secty[c][i])) &&
943 (!(new_x(capx[c] + 2) == sectx[c][i] &&
944 capy[c] == secty[c][i]))))) {
945 h = 3 * (5 - dmoun[i]) + dsea[i];
955 if (newk >= HILLMIN && newk < PLATMIN)
959 elev[sectx[c][where]][secty[c][where]] = newk;
960 dsea[where] = -INFINITY;
961 dmoun[where] = INFINITY;
964 /* Elevate the mountains and capitals */
966 for (i = 0; i < ns; ++i) {
967 if (ELEV == INFINITY) {
969 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
971 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
972 rnd((256 - HIGHMIN) / 2);
973 } else if ((c < nc &&
974 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
975 ((new_x(capx[c] + 2) == sectx[c][i] &&
976 capy[c] == secty[c][i])))
982 #define distance_to_land() distance_to_what(x, y, 1)
989 for (y = 0; y < WORLD_Y; ++y) {
990 for (x = y % 2; x < WORLD_X; x += 2) {
991 if (elev[x][y] == -INFINITY)
992 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
997 /****************************************************************************
999 ****************************************************************************/
1006 fert = LANDMIN - e + 40;
1007 else if (e < FERT_MAX)
1008 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1019 oil = (LANDMIN - e) * 2 + rnd(2);
1020 else if (e <= OIL_MAX)
1021 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1031 if (e >= IRON_MIN && e < HIGHMIN)
1032 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1042 if (e >= GOLD_MIN) {
1044 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1046 gold = 100 - 20 * HIGHMIN / e;
1057 if (e >= URAN_MIN && e < HIGHMIN)
1058 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1065 add_resources(struct sctstr *sct)
1067 sct->sct_fertil = set_fert(sct->sct_elev);
1068 sct->sct_oil = set_oil(sct->sct_elev);
1069 sct->sct_min = set_iron(sct->sct_elev);
1070 sct->sct_gmin = set_gold(sct->sct_elev);
1071 sct->sct_uran = set_uran(sct->sct_elev);
1074 /****************************************************************************
1075 DESIGNATE THE SECTORS
1076 ****************************************************************************/
1083 time_t current_time = time(NULL);
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 & 01), y, (s_char *)sct, current_time);
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, s_char *ptr, time_t timestamp)
1219 struct sctstr *sp = (struct sctstr *)ptr;
1221 sp->ef_type = EF_SECTOR;
1228 sp->sct_defense = 0;
1229 sp->sct_timestamp = timestamp;
1230 sp->sct_coastal = 1;
1234 set_coastal_flags(void)
1238 qprint("setting coastal flags...\n");
1239 for (i = 0; i < nc; ++i)
1240 for (j = 0; j < sc; j++)
1241 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];
1242 for (i = nc; i < nc + ni; ++i)
1243 for (j = 0; j < isecs[i]; j++)
1244 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];