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(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);
173 void print_vars(void);
175 void next_coast(int c, int x, int y, int *xp, int *yp);
176 void grow_islands(void);
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);
287 for (i = 1; i * i < n * 10000; ++i) ;
288 return (i + 50) / 100;
291 /****************************************************************************
292 PARSE COMMAND LINE ARGUMENTS
293 ****************************************************************************/
296 parse_args(int argc, char *argv[])
298 if (argc < 2 || argc > 8) {
299 puts("fairland syntax:\n");
300 puts("fairland [-e config] [-aiqo] [-s script] <nc> <sc> [<ni>] [<is>] [<sp>] [<pm>] [<di>] [<id>]");
301 puts("-q = quiet, -o = no ore produced");
302 puts("-a = Airport marker for continents, -i = islands not distinct");
303 printf("-e = read config file, -s = name of script (default %s)\n",
305 puts("nc = number of continents [MANDATORY]");
306 puts("sc = continent size [MANDATORY]");
307 puts("ni = number of islands (default = nc)");
308 puts("is = average size of islands (default = sc/2)");
309 printf("sp = spike percentage: 0 = round, 100 = snake (default = %d)\n",
311 printf("pm = the percentage of land that is mountain (default = %d)\n",
313 printf("di = the minimum distance between continents (default = %d)\n",
315 printf("id = minimum distance from islands to continents (default = %d)\n",
321 puts("fairland: error -- number of continents must be > 0");
327 puts("fairland: error -- size of continents must be > 0");
355 pm = DEFAULT_MOUNTAIN;
362 di = DEFAULT_CONTDIST;
365 puts("fairland: error -- distance between continents must be >= 0");
368 if (di > WORLD_X / 2 || di > WORLD_Y / 2) {
369 puts("fairland: error -- distance between continents too large");
376 id = DEFAULT_ISLDIST;
378 puts("fairland: error -- distance from islands to continents must be >= 0");
381 if (id > WORLD_X || id > WORLD_Y) {
382 puts("fairland: error -- distance from islands to continents too large");
385 if (nc * sc + nc * my_sqrt(sc) * 2 * (di + 1) > WORLD_X * WORLD_Y) {
386 puts("fairland: error -- world not big enough to fit continents.");
387 puts("arguments must satisfy:");
388 puts("nc*sc*sc + nc*sqrt(sc)*2*(di+1) < WORLD_X * WORLD_Y");
393 /****************************************************************************
394 VARIABLE INITIALIZATION
395 ****************************************************************************/
398 allocate_memory(void)
405 open(empfile[EF_SECTOR].file, O_RDWR | O_CREAT | O_TRUNC, 0660);
408 open(empfile[EF_SECTOR].file,
409 O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0660);
412 perror(empfile[EF_SECTOR].file);
416 (struct sctstr *)calloc((YSIZE * XSIZE), sizeof(struct sctstr));
417 sects = (struct sctstr **)calloc(YSIZE, sizeof(struct sctstr *));
418 for (i = 0; i < YSIZE; i++)
419 sects[i] = §sbuf[XSIZE * i];
422 srandom(now + getpid());
426 capx = (int *)calloc(nc, sizeof(int));
427 capy = (int *)calloc(nc, sizeof(int));
428 vector = (int *)calloc(WORLD_X + WORLD_Y, sizeof(int));
429 mc = (int *)calloc(STABLE_CYCLE, sizeof(int));
430 own = (int **)calloc(WORLD_X, sizeof(int *));
431 elev = (int **)calloc(WORLD_X, sizeof(int *));
432 for (i = 0; i < WORLD_X; ++i) {
433 own[i] = (int *)calloc(WORLD_Y, sizeof(int));
434 elev[i] = (int *)calloc(WORLD_Y, sizeof(int));
436 sectx = (int **)calloc(nc + ni, sizeof(int *));
437 secty = (int **)calloc(nc + ni, sizeof(int *));
438 sectc = (int **)calloc(nc + ni, sizeof(int *));
439 isecs = (int *)calloc(nc + ni, sizeof(int));
440 weight = (int *)calloc(max(sc, is * 2), sizeof(int));
441 dsea = (int *)calloc(max(sc, is * 2), sizeof(int));
442 dmoun = (int *)calloc(max(sc, is * 2), sizeof(int));
443 for (i = 0; i < nc; ++i) {
444 sectx[i] = (int *)calloc(sc, sizeof(int));
445 secty[i] = (int *)calloc(sc, sizeof(int));
446 sectc[i] = (int *)calloc(sc, sizeof(int));
448 for (i = nc; i < nc + ni; ++i) {
449 sectx[i] = (int *)calloc(is * 2, sizeof(int));
450 secty[i] = (int *)calloc(is * 2, sizeof(int));
451 sectc[i] = (int *)calloc(is * 2, sizeof(int));
460 int i, j, xx = 0, yy = 0;
465 for (i = 0; i < WORLD_X; ++i) {
466 for (j = 0; j < WORLD_Y; ++j) {
468 elev[i][j] = -INFINITY;
472 for (i = 0; i < nc; ++i, xx += 2) {
477 puts("fairland error: world not big enough for all the continents.\n");
484 for (i = 0; i < STABLE_CYCLE; ++i)
488 /****************************************************************************
489 DRIFT THE CAPITALS UNTIL THEY ARE AS FAR AWAY FROM EACH OTHER AS POSSIBLE
490 ****************************************************************************/
492 /* How isolated is capital j?
495 iso(int j, int newx, int newy)
497 int i, md, d = WORLD_X + WORLD_Y;
499 for (i = 0; i < nc; ++i) {
502 md = mapdist(capx[i], capy[i], newx, newy);
510 /* Drift all the capitals
517 for (turns = 0; turns < DRIFT_MAX; ++turns) {
518 if (turns > DRIFT_BEFORE_CHECK && (mind = stable()))
520 for (i = 0; i < nc; ++i)
526 /* Check to see if we have stabilized--can we stop drifting the capitals?
532 int i, isod, d = 0, stab = 1;
534 for (i = 0; i < nc; ++i) {
535 isod = iso(i, capx[i], capy[i]);
539 for (i = 0; i < STABLE_CYCLE; ++i)
543 mcc = (mcc + 1) % STABLE_CYCLE;
547 /* This routine does the actual drifting
553 int i, n, newx, newy;
555 for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
556 newx = new_x(capx[j] + dirx[i]);
557 newy = new_y(capy[j] + diry[i]);
558 if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
566 /****************************************************************************
568 ****************************************************************************/
570 /* Look for a coastal sector of continent c
578 for (i = 0; i < secs; ++i) {
580 for (j = 0; j < 6; ++j)
581 if (own[new_x(sectx[c][i] + dirx[j])][new_y(secty[c][i] + diry[j])] == -1)
586 /* Used for measuring distances
598 for (i = 1; i < n && vector[i] == vector[i - 1]; ++i) ;
601 return i > 1 || vector[0] > 0;
604 /* Test to see if we're allowed to grow there: the arguments di and id
607 try_to_grow(int c, int newx, int newy, int d)
611 for (i = 1; i <= d; ++i) {
612 for (j = 0; j < i; ++j)
617 for (j = 0; j < i; ++j) {
618 px = new_x(px + dirx[vector[j]]);
619 py = new_y(py + diry[vector[j]]);
621 if (own[px][py] != -1 &&
623 (DISTINCT_ISLANDS || own[px][py] < nc))
625 } while (next_vector(i));
627 sectx[c][secs] = newx;
628 secty[c][secs] = newy;
633 /* Move along the coast in a clockwise direction.
637 next_coast(int c, int x, int y, int *xp, int *yp)
639 int i, nx, ny, wat = 0;
647 for (i = 0; i < 12; ++i) {
648 nx = new_x(x + dirx[i % 6]);
649 ny = new_y(y + diry[i % 6]);
650 if (own[nx][ny] == -1)
652 if (wat && own[nx][ny] == c) {
660 /* Choose a sector to grow from
672 i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
677 } while (i != starti);
679 printf("fairland: BUG -- couldn't find coast for continent %c, sector %d.\nPlease mail stevens@math.utoronto.ca.\n",
688 /* Grow continent c by 1 sector
692 grow_one_sector(int c)
694 int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
696 spike = rnd(100) < sp;
697 if ((try1 = new_try(c)) == -1)
699 x = sx = sectx[c][try1];
700 y = sy = secty[c][try1];
705 for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
706 newx = new_x(x + dirx[i]);
707 newy = new_y(y + diry[i]);
708 if (own[newx][newy] == -1 &&
710 (own[new_x(x+dirx[(i+5)%6])][new_y(y+diry[(i+5)%6])] == -1 &&
711 own[new_x(x+dirx[(i+1)%6])][new_y(y+diry[(i+1)%6])] == -1)))
712 if (try_to_grow(c, newx, newy, c < nc ? di : id))
716 for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
717 newx = new_x(x + dirx[i]);
718 newy = new_y(y + diry[i]);
719 if (own[newx][newy] == -1)
720 if (try_to_grow(c, newx, newy, c < nc ? di : id))
723 next_coast(c, x, y, &x, &y);
725 } while (!done && coast_search < COAST_SEARCH_MAX &&
726 (secs == 1 || x != sx || y != sy));
727 if (!done && c < nc) {
729 printf("fairland: error -- continent %c had no room to grow!\n",
731 fl_status |= STATUS_NO_ROOM;
736 /* Grow all the continents
739 grow_continents(void)
743 for (c = 0; c < nc; ++c) {
744 sectx[c][0] = capx[c];
745 secty[c][0] = capy[c];
746 own[sectx[c][0]][secty[c][0]] = c;
747 sectx[c][1] = new_x(capx[c] + 2);
748 secty[c][1] = capy[c];
749 own[sectx[c][1]][secty[c][1]] = c;
752 for (secs = 2; secs < sc && !fl_status; ++secs) {
753 for (c = 0; c < nc; ++c) {
758 if (fl_status && !quiet)
759 printf("Only managed to grow %d out of %d sectors.\n", secs, sc);
763 /****************************************************************************
765 ****************************************************************************/
767 /* Choose a place to start growing an island from
770 place_island(int c, int *xp, int *yp)
773 int ssy = rnd(WORLD_Y);
774 int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
776 if (ssx > WORLD_X - 2)
777 ssx = new_x(ssx + 2);
778 for (d = di + id; d >= id; --d) {
782 for (*yp = sy; *xp != sx || *yp != sy; *xp += 2) {
783 if (*xp >= WORLD_X) {
784 *yp = new_y(*yp + 1);
786 if (*xp == sx && *yp == sy)
789 if (own[*xp][*yp] == -1 && try_to_grow(c, *xp, *yp, d))
796 /* Grow all the islands
804 for (c = nc; c < nc + ni; ++c) {
806 if (!place_island(c, &x, &y))
808 isiz = 1 + rnd(2 * is - 1);
812 } while (secs < isiz && grow_one_sector(c));
814 printf(" %d(%d)", c - nc + 1, secs);
820 /****************************************************************************
822 ****************************************************************************/
824 create_elevations(void)
830 /* Generic function for finding the distance to the closest sea, land, or
834 distance_to_what(int x, int y, int flag)
838 for (d = 1; d < 5; ++d) {
839 for (j = 0; j < d; ++j)
844 for (j = 0; j < d; ++j) {
845 px = new_x(px + dirx[vector[j]]);
846 py = new_y(py + diry[vector[j]]);
849 case 0: /* distance to sea */
850 if (own[px][py] == -1)
853 case 1: /* distance to land */
854 if (own[px][py] != -1)
857 case 2: /* distance to mountain */
858 if (elev[px][py] == INFINITY)
862 } while (next_vector(d));
867 #define ELEV elev[sectx[c][i]][secty[c][i]]
868 #define distance_to_sea() (sectc[c][i]?1:distance_to_what(sectx[c][i], secty[c][i], 0))
869 #define distance_to_mountain() distance_to_what(sectx[c][i], secty[c][i], 2)
871 /* Decide where the mountains go
876 int i, mountain_search, k, c, total, ns, nm, highest, where, h, newk,
879 for (c = 0; c < ctot; ++c) {
881 ns = (c < nc) ? sc : isecs[c];
882 nm = (pm * ns) / 100;
884 /* Place the mountains */
886 for (i = 0; i < ns; ++i) {
887 dsea[i] = distance_to_sea();
888 weight[i] = (total += (dsea[i] * dsea[i]));
891 for (k = nm, mountain_search = 0;
892 k && mountain_search < MOUNTAIN_SEARCH_MAX;
895 for (i = 0; i < ns; ++i)
896 if (r < weight[i] && ELEV == -INFINITY &&
898 ((!(capx[c] == sectx[c][i] &&
899 capy[c] == secty[c][i])) &&
900 (!(new_x(capx[c] + 2) == sectx[c][i] &&
901 capy[c] == secty[c][i]))))) {
908 /* Elevate land that is not mountain and not capital */
910 for (i = 0; i < ns; ++i)
911 dmoun[i] = distance_to_mountain();
912 dk = (ns - nm - ((c < nc) ? 3 : 1) > 0) ?
913 (100 * (HIGHMIN - LANDMIN)) / (ns - nm - ((c < nc) ? 3 : 1)) :
915 for (k = 100 * (HIGHMIN - 1);; k -= dk) {
918 for (i = 0; i < ns; ++i) {
919 if (ELEV != INFINITY &&
920 (c >= nc || ((!(capx[c] == sectx[c][i] &&
921 capy[c] == secty[c][i])) &&
922 (!(new_x(capx[c] + 2) == sectx[c][i] &&
923 capy[c] == secty[c][i]))))) {
924 h = 3 * (5 - dmoun[i]) + dsea[i];
934 if (newk >= HILLMIN && newk < PLATMIN)
938 elev[sectx[c][where]][secty[c][where]] = newk;
939 dsea[where] = -INFINITY;
940 dmoun[where] = INFINITY;
943 /* Elevate the mountains and capitals */
945 for (i = 0; i < ns; ++i) {
946 if (ELEV == INFINITY) {
948 ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
950 ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
951 rnd((256 - HIGHMIN) / 2);
952 } else if ((c < nc &&
953 ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
954 ((new_x(capx[c] + 2) == sectx[c][i] &&
955 capy[c] == secty[c][i])))
961 #define distance_to_land() distance_to_what(x, y, 1)
968 for (y = 0; y < WORLD_Y; ++y) {
969 for (x = y % 2; x < WORLD_X; x += 2) {
970 if (elev[x][y] == -INFINITY)
971 elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
976 /****************************************************************************
978 ****************************************************************************/
985 fert = LANDMIN - e + 40;
986 else if (e < FERT_MAX)
987 fert = (140 * (FERT_MAX - e)) / (FERT_MAX - LANDMIN);
998 oil = (LANDMIN - e) * 2 + rnd(2);
999 else if (e <= OIL_MAX)
1000 oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
1010 if (e >= IRON_MIN && e < HIGHMIN)
1011 iron = (120 * (e - IRON_MIN + 1)) / (HIGHMIN - IRON_MIN);
1021 if (e >= GOLD_MIN) {
1023 gold = (80 * (e - GOLD_MIN + 1)) / (HIGHMIN - GOLD_MIN);
1025 gold = 100 - 20 * HIGHMIN / e;
1036 if (e >= URAN_MIN && e < HIGHMIN)
1037 uran = (120 * (e - URAN_MIN + 1)) / (HIGHMIN - URAN_MIN);
1044 add_resources(struct sctstr *sct)
1046 sct->sct_fertil = set_fert(sct->sct_elev);
1047 sct->sct_oil = set_oil(sct->sct_elev);
1048 sct->sct_min = set_iron(sct->sct_elev);
1049 sct->sct_gmin = set_gold(sct->sct_elev);
1050 sct->sct_uran = set_uran(sct->sct_elev);
1053 /****************************************************************************
1054 DESIGNATE THE SECTORS
1055 ****************************************************************************/
1060 register struct sctstr *sct;
1063 /* sct = §s[0][0]; */
1065 for (y = 0; y < YSIZE; y++) {
1066 for (x = 0; x < XSIZE; x++, sct++) {
1067 fl_sct_init(x * 2 + (y & 01), y, (s_char *)sct);
1068 total = elev[sct->sct_x][y];
1069 if (total < LANDMIN) {
1070 sct->sct_type = SCT_WATER;
1071 } else if (total < HILLMIN)
1072 sct->sct_type = SCT_RURAL;
1073 else if (total < PLATMIN)
1074 sct->sct_type = SCT_MOUNT;
1075 else if (total < HIGHMIN)
1076 sct->sct_type = SCT_RURAL;
1078 sct->sct_type = SCT_MOUNT;
1079 sct->sct_elev = total;
1080 sct->sct_newtype = sct->sct_type;
1086 for (c = 0; c < nc; ++c) {
1087 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_type = SCT_AIRPT;
1088 sects[capy[c]][capx[c] / 2 + capy[c] % 2].sct_newtype = SCT_AIRPT;
1092 /****************************************************************************
1093 WRITE ALL THIS STUFF TO THE FILE
1094 ****************************************************************************/
1100 /* if ((n = write(the_file, sects, sizeof(sects))) < 0) { */
1101 if ((n = write(the_file, sectsbuf, YSIZE * XSIZE * sizeof(struct sctstr))) < 0) {
1102 perror(empfile[EF_SECTOR].file);
1105 if (n != (int)(YSIZE * XSIZE * sizeof(struct sctstr))) {
1106 printf("%s:partial write\n", empfile[EF_SECTOR].file);
1113 /****************************************************************************
1114 PRINT A PICTURE OF THE MAP TO YOUR SCREEN
1115 ****************************************************************************/
1121 translate_continents();
1123 for (i = 0; i < WORLD_Y; ++i) {
1127 for (j = i % 2; j < WORLD_X; j += 2) {
1128 if (own[j][i] == -1)
1131 printf("%c ", map_symbol(j, i));
1137 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");
1140 /* Reorder the continents from top left to bottom right */
1142 translate_continents(void)
1144 int i, j, n = 0, k, gotit, c;
1145 int *trans, *trans_cont, *oldcapx, *oldcapy;
1147 trans = (int *)calloc(nc, sizeof(int));
1148 trans_cont = (int *)calloc(nc, sizeof(int));
1149 oldcapx = (int *)calloc(nc, sizeof(int));
1150 oldcapy = (int *)calloc(nc, sizeof(int));
1152 for (i = 0; i < WORLD_Y; ++i) {
1153 for (j = i % 2; j < WORLD_X; j += 2) {
1154 if (own[j][i] > -1 && own[j][i] < nc) {
1156 for (k = 0; k < n; ++k) {
1157 if (trans[k] == own[j][i])
1162 printf("fairland: BUG in translate continents! mail stevens@math.utoronto.ca\n");
1165 trans[n] = own[j][i];
1166 trans_cont[own[j][i]] = n;
1172 for (i = 0; i < WORLD_Y; ++i) {
1173 for (j = i % 2; j < WORLD_X; j += 2) {
1174 if (own[j][i] > -1 && own[j][i] < nc) {
1175 own[j][i] = trans_cont[own[j][i]];
1179 for (c = 0; c < nc; ++c) {
1180 oldcapx[c] = capx[c];
1181 oldcapy[c] = capy[c];
1183 for (c = 0; c < nc; ++c) {
1184 capx[c] = oldcapx[trans[c]];
1185 capy[c] = oldcapy[trans[c]];
1190 map_symbol(int x, int y)
1194 for (c = 0; c < nc; ++c)
1195 if ((x == capx[c] && y == capy[c])
1196 || (x == new_x(capx[c] + 2) && y == capy[c]))
1198 if ((elev[x][y] >= HILLMIN && elev[x][y] < PLATMIN)
1199 || elev[x][y] >= HIGHMIN)
1201 return own[x][y] >= nc ? '%' : iscap ? '#' : numletter[own[x][y] % 62];
1204 /***************************************************************************
1205 WRITE A SCRIPT FOR PLACING CAPITALS
1206 ****************************************************************************/
1208 write_newcap_script(void)
1211 FILE *script = fopen(outfile, "w");
1214 printf("fairland: error, unable to write to %s.\n", outfile);
1218 for (c = 0; c < nc; ++c) {
1219 fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
1221 fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
1222 fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
1224 fprintf(script, "add %d visitor visitor v i\n", c + 1);
1228 printf("\n\nA script for adding all the countries can be found in \"%s\".\n",
1230 if (ORE && quiet == 0)
1231 printf("\t***IMPORTANT: Resources have already been added***\n\tYou do NOT need to run the ore program.\n");
1236 qprint(const char *str)
1243 fl_sct_init(coord x, coord y, s_char *ptr)
1245 struct sctstr *sp = (struct sctstr *)ptr;
1247 sp->ef_type = EF_SECTOR;
1254 sp->sct_defense = 0;