2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2000, 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 the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * fairland.c: Create a nice, new world
30 * Known contributors to this file:
35 /* define ORE 1 to add resources, define ORE 0 if you want to use another
36 program to add the resources */
40 /* If you don't specify these command line arguments, then these are the
42 #define DEFAULT_SPIKE 10
43 #define DEFAULT_MOUNTAIN 0
44 #define DEFAULT_CONTDIST 2
45 #define DEFAULT_ISLDIST 1
47 /* The following five numbers refer to elevation under which (in the case of
48 fertility or oil) or over which (in the case of iron, gold, and uranium)
49 sectors with that elevation will contain that resource. Elevation ranges
52 /* raise FERT_MAX for more fertility */
55 /* raise OIL_MAX for more oil */
58 /* lower IRON_MIN for more iron */
61 /* lower GOLD_MIN for more gold */
64 /* lower URAN_MIN for more uranium */
67 #if defined(aix) || defined(linux) || defined(solaris)
69 #endif /* aix or linux */
82 #include "prototypes.h"
84 /* do not change these 4 defines */
85 #define LANDMIN 1 /* plate altitude for normal land */
86 #define HILLMIN 34 /* plate altitude for hills */
87 #define PLATMIN 36 /* plate altitude for plateau */
88 #define HIGHMIN 98 /* plate altitude for mountains */
90 static void qprint _PROTO((const char *str));
92 static const char *outfile = "newcap_script";
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 #define XSIZE ((WORLD_X) / 2) /* basically world x-y size */
102 #define YSIZE (WORLD_Y)
103 #define STABLE_CYCLE 4 /* stability required for perterbed capitals */
104 #define INFINITY 999 /* a number which means "BIG" */
106 /* these defines prevent infinite loops:
109 #define COAST_SEARCH_MAX 200 /* how many times do we look for a coast sector
110 when growing continents and islands */
111 #define DRIFT_BEFORE_CHECK ((WORLD_X + WORLD_Y)/2)
112 #define DRIFT_MAX ((WORLD_X + WORLD_Y)*2)
113 #define MOUNTAIN_SEARCH_MAX 1000 /* how long do we try to place mountains */
118 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
119 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
121 #define max(a,b) (a>b?a:b)
123 #define rnd(x) (random() % (x))
125 int secs; /* number of sectors grown */
126 int ctot; /* total number of continents and islands grown */
127 int *isecs; /* array of how large each island is */
129 int nc, sc, di, sp, pm, ni, is, id; /* the 8 arguments to this program */
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 int the_file; /* 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 void parse_args(int argc, char *argv[]);
157 int allocate_memory(void);
160 void grow_continents(void);
161 void create_elevations(void);
162 void write_sects(void);
163 int write_file(void);
165 int write_newcap_script(void);
167 void elevate_land(void);
168 void elevate_sea(void);
169 void translate_continents(void);
170 int map_symbol(int x, int y);
171 static void fl_sct_init(coord x, coord y, s_char *ptr);
178 /****************************************************************************
180 ****************************************************************************/
183 main(int argc, char *argv[])
188 extern s_char *datadir;
189 char *config_file = NULL;
194 while ((opt = getopt(argc, argv, "ae:ioqs:")) != EOF) {
200 DISTINCT_ISLANDS = 0;
203 config_file = optarg;
217 if (config_file == NULL) {
218 sprintf(tbuf, "%s/econfig", datadir);
221 emp_config(config_file);
224 parse_args(argc - optind, argv + optind);
226 parse_args(argc - 1, argv + 1);
228 if (allocate_memory() == -1)
235 printf("\ntry #%d (out of %d)...", i + 1, NUMTRIES);
236 qprint("\n\n #*# ...fairland rips open a rift in the datumplane... #*#\n\n");
237 qprint("placing capitals...\n");
239 qprint("fairland: unstable drift -- try increasisg DRIFT_MAX\n");
240 qprint("growing continents...\n");
242 } while (fl_status && ++i < NUMTRIES);
244 fputs("ERROR: World not large enough to hold continents\n",
248 qprint("growing islands:");
250 qprint("\nelevating land...\n");
252 qprint("designating sectors...\n");
254 qprint("adding resources...\n");
256 qprint("writing to sectors file...\n");
257 if (write_file() == -1)
260 write_newcap_script();
269 puts("Creating a planet with:\n");
270 printf("%d continents\n", nc);
271 printf("continent size: %d\n", sc);
272 printf("number of islands: %d\n", ni);
273 printf("average size of islands: %d\n", is);
274 printf("spike: %d%%\n", sp);
275 printf("%d%% of land is mountain (each continent will have %d mountains)\n",
276 pm, (pm * sc) / 100);
277 printf("minimum distance between continents: %d\n", di);
278 printf("minimum distance from islands to continents: %d\n", id);
279 printf("World dimensions: %dx%d\n", WORLD_X, WORLD_Y);
288 for (i = 1; i * i < n * 10000; ++i) ;
289 return (i + 50) / 100;
292 /****************************************************************************
293 PARSE COMMAND LINE ARGUMENTS
294 ****************************************************************************/
297 parse_args(int argc, char *argv[])
299 if (argc < 2 || argc > 8) {
300 puts("fairland syntax:\n");
301 puts("fairland [-e config] [-aiqo] [-s script] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
302 puts("-q = quiet, -o = no ore produced");
303 puts("-a = Airport marker for continents, -i = islands not distinct");
304 printf("-e = read config file, -s = name of script (default %s)\n",
306 puts("nc = number of continents [MANDATORY]");
307 puts("sc = continent size [MANDATORY]");
308 puts("ni = number of islands (default = nc)");
309 puts("is = average size of islands (default = sc/2)");
310 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
312 printf("pm = the percentage of land that is mountain (default = %d)\n",
314 printf("di = the minimum distance between continents (default = %d)\n",
316 printf("id = minimum distance from islands to continents (default = %d)\n",
322 puts("fairland: error -- number of continents must be > 0");
328 puts("fairland: error -- size of continents must be > 0");
356 pm = DEFAULT_MOUNTAIN;
363 di = DEFAULT_CONTDIST;
366 puts("fairland: error -- distance between continents must be >= 0");
369 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
370 puts("fairland: error -- distance between continents too large");
377 id = DEFAULT_ISLDIST;
379 puts("fairland: error -- distance from islands to continents must be >= 0");
382 if (id > WORLD_X || id > WORLD_Y) {
383 puts("fairland: error -- distance from islands to continents too large");
386 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
387 puts("fairland: error -- world not big enough to fit continents.");
388 puts("arguments must satisfy:");
389 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
394 /****************************************************************************
395 VARIABLE INITIALIZATION
396 ****************************************************************************/
399 allocate_memory(void)
406 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
409 open(empfile[EF_SECTOR].file,
410 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
413 perror(empfile[EF_SECTOR].file);
417 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
418 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
419 for (i = 0; i < YSIZE; i++)
420 sects[i] = §sbuf[XSIZE * i];
423 srandom(now + getpid());
427 capx = (int *)calloc(nc, sizeof(int));
428 capy = (int *)calloc(nc, sizeof(int));
429 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
430 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
431 own = (int **)calloc(WORLD_X, sizeof(int *));
432 elev = (int **)calloc(WORLD_X, sizeof(int *));
433 for (i = 0; i < WORLD_X; ++i) {
434 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
435 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
437 sectx = (int **)calloc(nc + ni, sizeof(int *));
438 secty = (int **)calloc(nc + ni, sizeof(int *));
439 sectc = (int **)calloc(nc + ni, sizeof(int *));
440 isecs = (int *)calloc(nc + ni, sizeof(int));
441 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
442 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
443 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
444 for (i = 0; i < nc; ++i) {
445 sectx[i] = (int *)calloc(sc, sizeof(int));
446 secty[i] = (int *)calloc(sc, sizeof(int));
447 sectc[i] = (int *)calloc(sc, sizeof(int));
449 for (i = nc; i < nc + ni; ++i) {
450 sectx[i] = (int *)calloc(is * 2, sizeof(int));
451 secty[i] = (int *)calloc(is * 2, sizeof(int));
452 sectc[i] = (int *)calloc(is * 2, sizeof(int));
461 int i, j, xx = 0, yy = 0;
466 for (i = 0; i < WORLD_X; ++i) {
467 for (j = 0; j < WORLD_Y; ++j) {
469 elev[i][j] = -INFINITY;
473 for (i = 0; i < nc; ++i, xx += 2) {
478 puts("fairland error: world not big enough for all the continents.\n");
485 for (i = 0; i < STABLE_CYCLE; ++i)
489 /****************************************************************************
490 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
491 ****************************************************************************/
493 /* How isolated is capital j?
499 int i, md, d = WORLD_X + WORLD_Y;
501 for (i = 0; i < nc; ++i) {
504 md = mapdist(capx[i], capy[i], newx, newy);
512 /* Drift all the capitals
519 for (turns = 0; turns < DRIFT_MAX; ++turns) {
520 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
522 for (i = 0; i < nc; ++i)
528 /* Check to see if we have stabilized--can we stop drifting the capitals?
534 int i, isod, d = 0, stab = 1;
536 for (i = 0; i < nc; ++i) {
537 isod = iso(i, capx[i], capy[i]);
541 for (i = 0; i < STABLE_CYCLE; ++i)
545 mcc = (mcc + 1) % STABLE_CYCLE;
549 /* This routine does the actual drifting
556 int i, n, newx, newy;
558 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
559 newx = new_x(capx[j] + dirx[i]);
560 newy = new_y(capy[j] + diry[i]);
561 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
569 /****************************************************************************
571 ****************************************************************************/
573 /* Look for a coastal sector of continent c
582 for (i = 0; i < secs; ++i) {
584 for (j = 0; j < 6; ++j)
585 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
590 /* Used for measuring distances
603 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
606 return i > 1 || vector[0] > 0;
609 /* Test to see if we're allowed to grow there: the arguments di and id
612 try_to_grow(c, newx, newy, d)
613 int c, newx, newy, d;
617 for (i = 1; i <= d; ++i) {
618 for (j = 0; j < i; ++j)
623 for (j = 0; j < i; ++j) {
624 px = new_x(px + dirx[vector[j]]);
625 py = new_y(py + diry[vector[j]]);
627 if (own[px][py] != -1 &&
629 (DISTINCT_ISLANDS || own[px][py] < nc))
631 } while (next_vector(i));
633 sectx[c][secs] = newx;
634 secty[c][secs] = newy;
639 /* Move along the coast in a clockwise direction.
643 next_coast(c, x, y, xp, yp)
644 int c, x, y, *xp, *yp;
646 int i, nx, ny, wat = 0;
654 for (i = 0; i < 12; ++i) {
655 nx = new_x(x + dirx[i % 6]);
656 ny = new_y(y + diry[i % 6]);
657 if (own[nx][ny] == -1)
659 if (wat && own[nx][ny] == c) {
667 /* Choose a sector to grow from
679 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
684 } while (i != starti);
686 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
695 /* Grow continent c by 1 sector
702 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
704 spike = rnd(100) < sp;
705 if ((try1 = new_try(c)) == -1)
707 x = sx = sectx[c][try1];
708 y = sy = secty[c][try1];
713 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
714 newx = new_x(x + dirx[i]);
715 newy = new_y(y + diry[i]);
716 if (own[newx][newy] == -1 &&
718 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
719 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
720 if (try_to_grow(c, newx, newy, c < nc ? di : id))
724 for (i = rnd(6), n = 0; n < 6 && !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)
728 if (try_to_grow(c, newx, newy, c < nc ? di : id))
731 next_coast(c, x, y, &x, &y);
733 } while (!done && coast_search < COAST_SEARCH_MAX &&
734 (secs == 1 || x != sx || y != sy));
735 if (!done && c < nc) {
737 printf("fairland: error -- continent %c had no room to grow!\n",
739 fl_status |= STATUS_NO_ROOM;
744 /* Grow all the continents
747 grow_continents(void)
751 for (c = 0; c < nc; ++c) {
752 sectx[c][0] = capx[c];
753 secty[c][0] = capy[c];
754 own[sectx[c][0]][secty[c][0]] = c;
755 sectx[c][1] = new_x(capx[c] + 2);
756 secty[c][1] = capy[c];
757 own[sectx[c][1]][secty[c][1]] = c;
760 for (secs = 2; secs < sc && !fl_status; ++secs) {
761 for (c = 0; c < nc; ++c) {
766 if (fl_status && !quiet)
767 printf("Only managed to grow %d out of %d sectors.\n", secs, sc);
771 /****************************************************************************
773 ****************************************************************************/
775 /* Choose a place to start growing an island from
778 place_island(c, xp, yp)
782 int ssy = rnd(WORLD_Y);
783 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
785 if (ssx > WORLD_X - 2)
786 ssx = new_x(ssx + 2);
787 for (d = di + id; d >= id; --d) {
791 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
792 if (*xp >= WORLD_X) {
793 *yp = new_y(*yp + 1);
795 if (*xp == sx && *yp == sy)
798 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
805 /* Grow all the islands
813 for (c = nc; c < nc + ni; ++c) {
815 if (!place_island(c, &x, &y))
817 isiz = 1 + rnd(2 * is - 1);
821 } while (secs < isiz && grow_one_sector(c));
823 printf(" %d(%d)", c - nc + 1, secs);
829 /****************************************************************************
831 ****************************************************************************/
833 create_elevations(void)
839 /* Generic function for finding the distance to the closest sea, land, or
843 distance_to_what(x, y, flag)
848 for (d = 1; d < 5; ++d) {
849 for (j = 0; j < d; ++j)
854 for (j = 0; j < d; ++j) {
855 px = new_x(px + dirx[vector[j]]);
856 py = new_y(py + diry[vector[j]]);
859 case 0: /* distance to sea */
860 if (own[px][py] == -1)
863 case 1: /* distance to land */
864 if (own[px][py] != -1)
867 case 2: /* distance to mountain */
868 if (elev[px][py] == INFINITY)
872 } while (next_vector(d));
877 #define ELEV elev[sectx[c][i]][secty[c][i]]
878 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
879 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
881 /* Decide where the mountains go
886 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
889 for (c = 0; c < ctot; ++c) {
891 ns = (c < nc) ? sc : isecs[c];
892 nm = (pm * ns) / 100;
894 /* Place the mountains */
896 for (i = 0; i < ns; ++i) {
897 dsea[i] = distance_to_sea();
898 weight[i] = (total += (dsea[i] * dsea[i]));
901 for (k = nm, mountain_search = 0;
902 k && mountain_search < MOUNTAIN_SEARCH_MAX;
905 for (i = 0; i < ns; ++i)
906 if (r < weight[i] && ELEV == -INFINITY &&
908 ((!(capx[c] == sectx[c][i] &&
909 capy[c] == secty[c][i])) &&
910 (!(new_x(capx[c] + 2) == sectx[c][i] &&
911 capy[c] == secty[c][i]))))) {
918 /* Elevate land that is not mountain and not capital */
920 for (i = 0; i < ns; ++i)
921 dmoun[i] = distance_to_mountain();
922 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
923 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
925 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
928 for (i = 0; i < ns; ++i) {
929 if (ELEV != INFINITY &&
930 (c >= nc || ((!(capx[c] == sectx[c][i] &&
931 capy[c] == secty[c][i])) &&
932 (!(new_x(capx[c] + 2) == sectx[c][i] &&
933 capy[c] == secty[c][i]))))) {
934 h = 3 * (5 - dmoun[i]) + dsea[i];
944 if (newk >= HILLMIN && newk < PLATMIN)
948 elev[sectx[c][where]][secty[c][where]] = newk;
949 dsea[where] = -INFINITY;
950 dmoun[where] = INFINITY;
953 /* Elevate the mountains and capitals */
955 for (i = 0; i < ns; ++i) {
956 if (ELEV == INFINITY) {
958 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
960 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
961 rnd((256 - HIGHMIN) / 2);
962 } else if ((c < nc &&
963 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
964 ((new_x(capx[c] + 2) == sectx[c][i] &&
965 capy[c] == secty[c][i])))
971 #define distance_to_land() distance_to_what(x, y, 1)
978 for (y = 0; y < WORLD_Y; ++y) {
979 for (x = y % 2; x < WORLD_X; x += 2) {
980 if (elev[x][y] == -INFINITY)
981 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
986 /****************************************************************************
988 ****************************************************************************/
996 fert = LANDMIN - e + 40;
997 else if (e < FERT_MAX)
998 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
1010 oil = (LANDMIN - e) * 2 + rnd(2);
1011 else if (e <= OIL_MAX)
1012 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1023 if (e >= IRON_MIN && e < HIGHMIN)
1024 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1035 if (e >= GOLD_MIN) {
1037 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1039 gold = 100 - 20 * HIGHMIN / e;
1051 if (e >= URAN_MIN && e < HIGHMIN)
1052 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1062 sct->sct_fertil = set_fert(sct->sct_elev);
1063 sct->sct_oil = set_oil(sct->sct_elev);
1064 sct->sct_min = set_iron(sct->sct_elev);
1065 sct->sct_gmin = set_gold(sct->sct_elev);
1066 sct->sct_uran = set_uran(sct->sct_elev);
1069 /****************************************************************************
1070 DESIGNATE THE SECTORS
1071 ****************************************************************************/
1076 register struct sctstr *sct;
1079 /* sct = §s[0][0]; */
1081 for (y = 0; y < YSIZE; y++) {
1082 for (x = 0; x < XSIZE; x++, sct++) {
1083 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1084 total = elev[sct->sct_x][y];
1085 if (total < LANDMIN) {
1086 sct->sct_type = SCT_WATER;
1087 } else if (total < HILLMIN)
1088 sct->sct_type = SCT_RURAL;
1089 else if (total < PLATMIN)
1090 sct->sct_type = SCT_MOUNT;
1091 else if (total < HIGHMIN)
1092 sct->sct_type = SCT_RURAL;
1094 sct->sct_type = SCT_MOUNT;
1095 sct->sct_elev = total;
1096 sct->sct_newtype = sct->sct_type;
1102 for (c = 0; c < nc; ++c) {
1103 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1104 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1108 /****************************************************************************
1109 WRITE ALL THIS STUFF TO THE FILE
1110 ****************************************************************************/
1116 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1117 if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1118 perror(empfile[EF_SECTOR].file);
1121 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1122 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1129 /****************************************************************************
1130 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1131 ****************************************************************************/
1137 translate_continents();
1139 for (i = 0; i < WORLD_Y; ++i) {
1143 for (j = i % 2; j < WORLD_X; j += 2) {
1144 if (own[j][i] == -1)
1147 printf("%c ", map_symbol(j, i));
1153 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");
1156 /* Reorder the continents from top left to bottom right */
1158 translate_continents(void)
1160 int i, j, n = 0, k, gotit, c;
1161 int *trans, *trans_cont, *oldcapx, *oldcapy;
1163 trans = (int *)calloc(nc, sizeof(int));
1164 trans_cont = (int *)calloc(nc, sizeof(int));
1165 oldcapx = (int *)calloc(nc, sizeof(int));
1166 oldcapy = (int *)calloc(nc, sizeof(int));
1168 for (i = 0; i < WORLD_Y; ++i) {
1169 for (j = i % 2; j < WORLD_X; j += 2) {
1170 if (own[j][i] > -1 && own[j][i] < nc) {
1172 for (k = 0; k < n; ++k) {
1173 if (trans[k] == own[j][i])
1178 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1181 trans[n] = own[j][i];
1182 trans_cont[own[j][i]] = n;
1188 for (i = 0; i < WORLD_Y; ++i) {
1189 for (j = i % 2; j < WORLD_X; j += 2) {
1190 if (own[j][i] > -1 && own[j][i] < nc) {
1191 own[j][i] = trans_cont[own[j][i]];
1195 for (c = 0; c < nc; ++c) {
1196 oldcapx[c] = capx[c];
1197 oldcapy[c] = capy[c];
1199 for (c = 0; c < nc; ++c) {
1200 capx[c] = oldcapx[trans[c]];
1201 capy[c] = oldcapy[trans[c]];
1206 map_symbol(int x, int y)
1210 for (c = 0; c < nc; ++c)
1211 if ((x == capx[c] && y == capy[c])
1212 || (x == new_x(capx[c] + 2) && y == capy[c]))
1214 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1215 || elev[x][y] >= HIGHMIN)
1217 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1220 /***************************************************************************
1221 WRITE A SCRIPT FOR PLACING CAPITALS
1222 ****************************************************************************/
1224 write_newcap_script(void)
1227 FILE *script = fopen(outfile, "w");
1230 printf("fairland: error, unable to write to %s.\n", outfile);
1234 for (c = 0; c < nc; ++c) {
1235 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1237 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1238 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1240 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1244 printf("\n\nA script for adding all the countries can be found in \"%s\".\n",
1246 if (ORE && quiet == 0)
1247 printf("\t***IMPORTANT: Resources have already been added***\n\tYou do NOT need to run the ore program.\n");
1260 fl_sct_init(coord x, coord y, s_char *ptr)
1262 struct sctstr *sp = (struct sctstr *)ptr;
1264 sp->ef_type = EF_SECTOR;
1271 sp->sct_defense = 0;