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"
88 /* do not change these 4 defines */
89 #define LANDMIN 1 /* plate altitude for normal land */
90 #define HILLMIN 34 /* plate altitude for hills */
91 #define PLATMIN 36 /* plate altitude for plateau */
92 #define HIGHMIN 98 /* plate altitude for mountains */
94 static void qprint(const char * const fmt, ...)
95 ATTRIBUTE((format (printf, 1, 2)));
97 #define DEFAULT_OUTFILE_NAME "newcap_script"
98 static const char *outfile = DEFAULT_OUTFILE_NAME;
99 /* mark the continents with a * so you can tell them
100 from the islands 1 = mark, 0 = don't mark. */
101 static int AIRPORT_MARKER = 0;
103 /* don't let the islands crash into each other.
104 1 = don't merge, 0 = merge. */
105 static int DISTINCT_ISLANDS = 1;
107 static char *program_name;
109 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
110 #define YSIZE (WORLD_Y)
111 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
112 #define INFINITY 999 /* a number which means "BIG" */
114 /* these defines prevent infinite loops:
117 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
118 when growing continents and islands */
119 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
120 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
121 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
126 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
127 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
128 #define rnd(x) (random() % (x))
130 int secs; /* number of sectors grown */
131 int ctot; /* total number of continents and islands grown */
132 int *isecs; /* array of how large each island is */
134 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
135 unsigned long rnd_seed; /* optional seed can be passed as an argument */
136 int *capx, *capy; /* location of the nc capitals */
137 int *mc, mcc; /* array and counter used for stability
138 check when perturbing */
139 int spike; /* are we spiking? */
140 int mind; /* the final distance between capitals that
142 int dirx[] = { -2, -1, 1, 2, 1, -1 }; /* gyujnb */
143 int diry[] = { 0, -1, -1, 0, 1, 1 };
145 int **own; /* owner of the sector. -1 means water */
146 int **elev; /* elevation of the sectors */
147 int **sectx, **secty; /* the sectors for each continent */
148 int **sectc; /* which sectors are on the coast? */
149 int *vector; /* used for measuring distances */
150 int *weight; /* used for placing mountains */
151 int *dsea, *dmoun; /* the dist to the ocean and mountain */
152 FILE *sect_fptr; /* the file we write everything to */
153 struct sctstr **sects;
154 struct sctstr *sectsbuf;
155 int fl_status; /* is anything wrong? */
156 #define STATUS_NO_ROOM 1 /* there was no room to grow */
157 #define NUMTRIES 10 /* keep trying to grow this many times */
159 const char *numletter =
160 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
162 static void help(char *);
163 static void usage(void);
164 static void parse_args(int argc, char *argv[]);
165 static int allocate_memory(void);
166 static void init(void);
167 static int drift(void);
168 static void grow_continents(void);
169 static void create_elevations(void);
170 static void write_sects(void);
171 static int write_file(void);
172 static void output(void);
173 static int write_newcap_script(void);
174 static int stable(void);
175 static void elevate_land(void);
176 static void elevate_sea(void);
177 static int map_symbol(int x, int y);
178 static void fl_sct_init(coord, coord, struct sctstr *, time_t timestamp);
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:hioqR:s:v")) != EOF) {
206 config_file = optarg;
209 DISTINCT_ISLANDS = 0;
218 rnd_seed = strtoul(optarg, NULL, 10);
227 printf("%s\n\n%s", version, legal);
235 if (emp_config(config_file))
238 parse_args(argc - optind, argv + optind);
239 if (allocate_memory() == -1)
246 qprint("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
247 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
248 qprint("seed is %lu\n", rnd_seed);
249 qprint("placing capitals...\n");
251 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
252 qprint("growing continents...\n");
254 } while (fl_status && ++i < NUMTRIES);
256 fputs("ERROR: World not large enough to hold continents\n",
260 qprint("growing islands:");
262 qprint("\nelevating land...\n");
264 qprint("designating sectors...\n");
266 qprint("adding resources...\n");
268 qprint("writing to sectors file...\n");
269 if (write_file() == -1)
272 write_newcap_script();
274 qprint("\t*** Resources have not been added ***\n");
283 puts("Creating a planet with:\n");
284 printf("%d continents\n", nc);
285 printf("continent size: %d\n", sc);
286 printf("number of islands: %d\n", ni);
287 printf("average size of islands: %d\n", is);
288 printf("spike: %d%%\n", sp);
289 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
290 pm, (pm * sc) / 100);
291 printf("minimum distance between continents: %d\n", di);
292 printf("minimum distance from islands to continents: %d\n", id);
293 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
301 for (i = 1; i * i < n * 10000; ++i) ;
302 return (i + 50) / 100;
305 /****************************************************************************
306 PARSE COMMAND LINE ARGUMENTS
307 ****************************************************************************/
310 help(char *complaint)
313 fprintf(stderr, "%s: %s\n", program_name, complaint);
314 fprintf(stderr, "Try -h for help.\n");
320 printf("Usage: %s [OPTION]... NC SC [NI] [IS] [SP] [PM] [DI] [ID]\n"
321 " -a airport marker for continents\n"
322 " -e CONFIG-FILE configuration file\n"
324 " -h display this help and exit\n"
325 " -i islands may merge\n"
326 " -o don't set resources\n"
328 " -R SEED seed for random number generator\n"
329 " -s SCRIPT name of script to create (default %s)\n"
330 " NC number of continents\n"
331 " SC continent size\n"
332 " NI number of islands (default NC)\n"
333 " IS average island size (default SC/2)\n"
334 " SP spike percentage: 0 = round, 100 = snake (default %d)\n"
335 " PM percentage of land that is mountain (default %d)\n"
336 " DI minimum distance between continents (default %d)\n"
337 " ID minimum distance from islands to continents (default %d)\n",
338 program_name, dflt_econfig, DEFAULT_OUTFILE_NAME,
339 DEFAULT_SPIKE, DEFAULT_MOUNTAIN, DEFAULT_CONTDIST, DEFAULT_ISLDIST);
343 parse_args(int argc, char *argv[])
346 help("missing arguments");
350 help("too many arguments");
355 puts("fairland: error -- number of continents must be > 0");
361 puts("fairland: error -- size of continents must be > 0");
389 pm = DEFAULT_MOUNTAIN;
396 di = DEFAULT_CONTDIST;
399 puts("fairland: error -- distance between continents must be >= 0");
402 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
403 puts("fairland: error -- distance between continents too large");
410 id = DEFAULT_ISLDIST;
412 puts("fairland: error -- distance from islands to continents must be >= 0");
415 if (id > WORLD_X || id > WORLD_Y) {
416 puts("fairland: error -- distance from islands to continents too large");
419 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
420 puts("fairland: error -- world not big enough to fit continents.");
421 puts("arguments must satisfy:");
422 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
427 /****************************************************************************
428 VARIABLE INITIALIZATION
429 ****************************************************************************/
432 allocate_memory(void)
437 fname = malloc(strlen(gamedir) + 1 + strlen(empfile[EF_SECTOR].file) + 1);
438 sprintf(fname, "%s/%s", gamedir, empfile[EF_SECTOR].file);
439 sect_fptr = fopen(fname, "wb");
440 if (sect_fptr == NULL) {
445 sectsbuf = calloc((YSIZE * XSIZE), sizeof(struct sctstr));
446 sects = calloc(YSIZE, sizeof(struct sctstr *));
447 for (i = 0; i < YSIZE; i++)
448 sects[i] = §sbuf[XSIZE * i];
449 capx = calloc(nc, sizeof(int));
450 capy = calloc(nc, sizeof(int));
451 vector = calloc(WORLD_X + WORLD_Y, sizeof(int));
452 mc = calloc(STABLE_CYCLE, sizeof(int));
453 own = calloc(WORLD_X, sizeof(int *));
454 elev = calloc(WORLD_X, sizeof(int *));
455 for (i = 0; i < WORLD_X; ++i) {
456 own[i] = calloc(WORLD_Y, sizeof(int));
457 elev[i] = calloc(WORLD_Y, sizeof(int));
459 sectx = calloc(nc + ni, sizeof(int *));
460 secty = calloc(nc + ni, sizeof(int *));
461 sectc = calloc(nc + ni, sizeof(int *));
462 isecs = calloc(nc + ni, sizeof(int));
463 weight = calloc(MAX(sc, is * 2), sizeof(int));
464 dsea = calloc(MAX(sc, is * 2), sizeof(int));
465 dmoun = calloc(MAX(sc, is * 2), sizeof(int));
466 for (i = 0; i < nc; ++i) {
467 sectx[i] = calloc(sc, sizeof(int));
468 secty[i] = calloc(sc, sizeof(int));
469 sectc[i] = calloc(sc, sizeof(int));
471 for (i = nc; i < nc + ni; ++i) {
472 sectx[i] = calloc(is * 2, sizeof(int));
473 secty[i] = calloc(is * 2, sizeof(int));
474 sectc[i] = calloc(is * 2, sizeof(int));
483 int i, j, xx = 0, yy = 0;
488 for (i = 0; i < WORLD_X; ++i) {
489 for (j = 0; j < WORLD_Y; ++j) {
491 elev[i][j] = -INFINITY;
495 for (i = 0; i < nc; ++i, xx += 2) {
500 puts("fairland error: world not big enough for all the continents.\n");
507 for (i = 0; i < STABLE_CYCLE; ++i)
511 /****************************************************************************
512 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
513 ****************************************************************************/
515 /* How isolated is capital j?
518 iso(int j, int newx, int newy)
520 int i, md, d = WORLD_X + WORLD_Y;
522 for (i = 0; i < nc; ++i) {
525 md = mapdist(capx[i], capy[i], newx, newy);
533 /* Drift all the capitals
540 for (turns = 0; turns < DRIFT_MAX; ++turns) {
541 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
543 for (i = 0; i < nc; ++i)
549 /* Check to see if we have stabilized--can we stop drifting the capitals?
555 int i, isod, d = 0, stab = 1;
557 for (i = 0; i < nc; ++i) {
558 isod = iso(i, capx[i], capy[i]);
562 for (i = 0; i < STABLE_CYCLE; ++i)
566 mcc = (mcc + 1) % STABLE_CYCLE;
570 /* This routine does the actual drifting
576 int i, n, newx, newy;
578 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
579 newx = new_x(capx[j] + dirx[i]);
580 newy = new_y(capy[j] + diry[i]);
581 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
589 /****************************************************************************
591 ****************************************************************************/
593 /* Look for a coastal sector of continent c
601 for (i = 0; i < secs; ++i) {
603 for (j = 0; j < 6; ++j)
604 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
609 /* Used for measuring distances
621 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
624 return i > 1 || vector[0] > 0;
627 /* Test to see if we're allowed to grow there: the arguments di and id
630 try_to_grow(int c, int newx, int newy, int d)
634 for (i = 1; i <= d; ++i) {
635 for (j = 0; j < i; ++j)
640 for (j = 0; j < i; ++j) {
641 px = new_x(px + dirx[vector[j]]);
642 py = new_y(py + diry[vector[j]]);
644 if (own[px][py] != -1 &&
646 (DISTINCT_ISLANDS || own[px][py] < nc))
648 } while (next_vector(i));
650 sectx[c][secs] = newx;
651 secty[c][secs] = newy;
656 /* Move along the coast in a clockwise direction.
660 next_coast(int c, int x, int y, int *xp, int *yp)
662 int i, nx, ny, wat = 0;
670 for (i = 0; i < 12; ++i) {
671 nx = new_x(x + dirx[i % 6]);
672 ny = new_y(y + diry[i % 6]);
673 if (own[nx][ny] == -1)
675 if (wat && own[nx][ny] == c) {
683 /* Choose a sector to grow from
695 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
700 } while (i != starti);
702 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
711 /* Grow continent c by 1 sector
715 grow_one_sector(int c)
717 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
719 spike = rnd(100) < sp;
720 if ((try1 = new_try(c)) == -1)
722 x = sx = sectx[c][try1];
723 y = sy = secty[c][try1];
728 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
729 newx = new_x(x + dirx[i]);
730 newy = new_y(y + diry[i]);
731 if (own[newx][newy] == -1 &&
733 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
734 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
735 if (try_to_grow(c, newx, newy, c < nc ? di : id))
739 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
740 newx = new_x(x + dirx[i]);
741 newy = new_y(y + diry[i]);
742 if (own[newx][newy] == -1)
743 if (try_to_grow(c, newx, newy, c < nc ? di : id))
746 next_coast(c, x, y, &x, &y);
748 } while (!done && coast_search < COAST_SEARCH_MAX &&
749 (secs == 1 || x != sx || y != sy));
750 if (!done && c < nc) {
751 qprint("fairland: error -- continent %c had no room to grow!\n",
753 fl_status |= STATUS_NO_ROOM;
758 /* Grow all the continents
761 grow_continents(void)
765 for (c = 0; c < nc; ++c) {
766 sectx[c][0] = capx[c];
767 secty[c][0] = capy[c];
768 own[sectx[c][0]][secty[c][0]] = c;
769 sectx[c][1] = new_x(capx[c] + 2);
770 secty[c][1] = capy[c];
771 own[sectx[c][1]][secty[c][1]] = c;
774 for (secs = 2; secs < sc && !fl_status; ++secs) {
775 for (c = 0; c < nc; ++c) {
780 for (c = 0; c < nc; ++c)
784 qprint("Only managed to grow %d out of %d sectors.\n", secs, sc);
788 /****************************************************************************
790 ****************************************************************************/
792 /* Choose a place to start growing an island from
795 place_island(int c, int *xp, int *yp)
798 int ssy = rnd(WORLD_Y);
799 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
801 if (ssx > WORLD_X - 2)
802 ssx = new_x(ssx + 2);
803 for (d = di + id; d >= id; --d) {
807 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
808 if (*xp >= WORLD_X) {
809 *yp = new_y(*yp + 1);
811 if (*xp == sx && *yp == sy)
814 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
821 /* Grow all the islands
829 for (c = nc; c < nc + ni; ++c) {
831 if (!place_island(c, &x, &y))
833 isiz = 1 + rnd(2 * is - 1);
837 } while (secs < isiz && grow_one_sector(c));
839 qprint(" %d(%d)", c - nc + 1, secs);
845 /****************************************************************************
847 ****************************************************************************/
849 create_elevations(void)
855 /* Generic function for finding the distance to the closest sea, land, or
859 distance_to_what(int x, int y, int flag)
863 for (d = 1; d < 5; ++d) {
864 for (j = 0; j < d; ++j)
869 for (j = 0; j < d; ++j) {
870 px = new_x(px + dirx[vector[j]]);
871 py = new_y(py + diry[vector[j]]);
874 case 0: /* distance to sea */
875 if (own[px][py] == -1)
878 case 1: /* distance to land */
879 if (own[px][py] != -1)
882 case 2: /* distance to mountain */
883 if (elev[px][py] == INFINITY)
887 } while (next_vector(d));
892 #define ELEV elev[sectx[c][i]][secty[c][i]]
893 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
894 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
896 /* Decide where the mountains go
901 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
904 for (c = 0; c < ctot; ++c) {
906 ns = (c < nc) ? sc : isecs[c];
907 nm = (pm * ns) / 100;
909 /* Place the mountains */
911 for (i = 0; i < ns; ++i) {
912 dsea[i] = distance_to_sea();
913 weight[i] = (total += (dsea[i] * dsea[i]));
916 for (k = nm, mountain_search = 0;
917 k && mountain_search < MOUNTAIN_SEARCH_MAX;
920 for (i = 0; i < ns; ++i)
921 if (r < weight[i] && ELEV == -INFINITY &&
923 ((!(capx[c] == sectx[c][i] &&
924 capy[c] == secty[c][i])) &&
925 (!(new_x(capx[c] + 2) == sectx[c][i] &&
926 capy[c] == secty[c][i]))))) {
933 /* Elevate land that is not mountain and not capital */
935 for (i = 0; i < ns; ++i)
936 dmoun[i] = distance_to_mountain();
937 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
938 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
940 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
943 for (i = 0; i < ns; ++i) {
944 if (ELEV != INFINITY &&
945 (c >= nc || ((!(capx[c] == sectx[c][i] &&
946 capy[c] == secty[c][i])) &&
947 (!(new_x(capx[c] + 2) == sectx[c][i] &&
948 capy[c] == secty[c][i]))))) {
949 h = 3 * (5 - dmoun[i]) + dsea[i];
959 if (newk >= HILLMIN && newk < PLATMIN)
963 elev[sectx[c][where]][secty[c][where]] = newk;
964 dsea[where] = -INFINITY;
965 dmoun[where] = INFINITY;
968 /* Elevate the mountains and capitals */
970 for (i = 0; i < ns; ++i) {
971 if (ELEV == INFINITY) {
973 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
975 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
976 rnd((256 - HIGHMIN) / 2);
977 } else if ((c < nc &&
978 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
979 ((new_x(capx[c] + 2) == sectx[c][i] &&
980 capy[c] == secty[c][i])))
986 #define distance_to_land() distance_to_what(x, y, 1)
993 for (y = 0; y < WORLD_Y; ++y) {
994 for (x = y % 2; x < WORLD_X; x += 2) {
995 if (elev[x][y] == -INFINITY)
996 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
1001 /****************************************************************************
1003 ****************************************************************************/
1010 fert = LANDMIN - e + 40;
1011 else if (e < FERT_MAX)
1012 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1023 oil = (LANDMIN - e) * 2 + rnd(2);
1024 else if (e <= OIL_MAX)
1025 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1035 if (e >= IRON_MIN && e < HIGHMIN)
1036 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1046 if (e >= GOLD_MIN) {
1048 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1050 gold = 100 - 20 * HIGHMIN / e;
1061 if (e >= URAN_MIN && e < HIGHMIN)
1062 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1069 add_resources(struct sctstr *sct)
1071 sct->sct_fertil = set_fert(sct->sct_elev);
1072 sct->sct_oil = set_oil(sct->sct_elev);
1073 sct->sct_min = set_iron(sct->sct_elev);
1074 sct->sct_gmin = set_gold(sct->sct_elev);
1075 sct->sct_uran = set_uran(sct->sct_elev);
1078 /****************************************************************************
1079 DESIGNATE THE SECTORS
1080 ****************************************************************************/
1087 time_t current_time = time(NULL);
1089 /* sct = §s[0][0]; */
1091 for (y = 0; y < YSIZE; y++) {
1092 for (x = 0; x < XSIZE; x++, sct++) {
1093 fl_sct_init(x * 2 + (y & 1), y, sct, current_time);
1094 total = elev[sct->sct_x][y];
1095 if (total < LANDMIN) {
1096 sct->sct_type = SCT_WATER;
1097 } else if (total < HILLMIN)
1098 sct->sct_type = SCT_RURAL;
1099 else if (total < PLATMIN)
1100 sct->sct_type = SCT_MOUNT;
1101 else if (total < HIGHMIN)
1102 sct->sct_type = SCT_RURAL;
1104 sct->sct_type = SCT_MOUNT;
1105 sct->sct_elev = total;
1106 sct->sct_newtype = sct->sct_type;
1112 for (c = 0; c < nc; ++c) {
1113 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1114 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1116 set_coastal_flags();
1119 /****************************************************************************
1120 WRITE ALL THIS STUFF TO THE FILE
1121 ****************************************************************************/
1127 n = fwrite(sectsbuf, sizeof(struct sctstr), YSIZE * XSIZE, sect_fptr);
1129 perror(empfile[EF_SECTOR].file);
1132 if (n != YSIZE * XSIZE) {
1133 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1140 /****************************************************************************
1141 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1142 ****************************************************************************/
1148 for (i = 0; i < WORLD_Y; ++i) {
1152 for (j = i % 2; j < WORLD_X; j += 2) {
1153 if (own[j][i] == -1)
1156 printf("%c ", map_symbol(j, i));
1162 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");
1166 map_symbol(int x, int y)
1170 for (c = 0; c < nc; ++c)
1171 if ((x == capx[c] && y == capy[c])
1172 || (x == new_x(capx[c] + 2) && y == capy[c]))
1174 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1175 || elev[x][y] >= HIGHMIN)
1177 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1180 /***************************************************************************
1181 WRITE A SCRIPT FOR PLACING CAPITALS
1182 ****************************************************************************/
1184 write_newcap_script(void)
1187 FILE *script = fopen(outfile, "w");
1190 printf("fairland: error, unable to write to %s.\n", outfile);
1194 for (c = 0; c < nc; ++c) {
1195 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1197 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1198 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1200 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1203 qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
1209 qprint(const char * const fmt, ...)
1215 vfprintf(stdout, fmt, ap);
1221 fl_sct_init(coord x, coord y, struct sctstr *sp, time_t timestamp)
1223 sp->ef_type = EF_SECTOR;
1230 sp->sct_defense = 0;
1231 sp->sct_timestamp = timestamp;
1232 sp->sct_coastal = 1;
1236 set_coastal_flags(void)
1240 qprint("setting coastal flags...\n");
1241 for (i = 0; i < nc; ++i)
1242 for (j = 0; j < sc; j++)
1243 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];
1244 for (i = nc; i < nc + ni; ++i)
1245 for (j = 0; j < isecs[i]; j++)
1246 sects[secty[i][j]][sectx[i][j] / 2].sct_coastal = sectc[i][j];