games-request@tekred.UUCP (07/10/87)
Submitted by: "Stanley T. Shebs" <shebs%orion@cs.utah.edu> Comp.sources.games: Volume 1, Issue 86 Archive-name: xconq/Part06 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 7)." # Contents: bitmaps.h greek.u init.c input.c output.c side.c util.c # Wrapped by billr@tekred on Thu Jul 9 17:45:50 1987 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f bitmaps.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"bitmaps.h\" else echo shar: Extracting \"bitmaps.h\" \(2639 characters\) sed "s/^X//" >bitmaps.h <<'END_OF_bitmaps.h' X/* Copyright (c) 1987 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: bitmaps.h,v 1.5 87/06/06 20:04:13 shebs Exp $ */ X X#define cmask_width 16 X#define cmask_height 16 Xstatic short cmask_bits[] = { X 0xffff, 0x8001, 0xbffd, 0xa005, X 0xa005, 0xa005, 0xa005, 0xa005, X 0xa005, 0xa005, 0xa005, 0xa005, X 0xa005, 0xbffd, 0x8001, 0xffff}; X X#define ccurs_width 16 X#define ccurs_height 16 Xstatic short ccurs_bits[] = { X 0x0000, 0x7ffe, 0x4002, 0x4002, X 0x4002, 0x4002, 0x4002, 0x4002, X 0x4002, 0x4002, 0x4002, 0x4002, X 0x4002, 0x4002, 0x7ffe, 0x0000}; X X#define mcurs_width 16 X#define mcurs_height 16 Xstatic short mcurs_bits[] = { X 0x03e0, 0x0c98, 0x1084, 0x2082, X 0x2082, 0x4081, 0x4081, 0x7fff, X 0x4081, 0x4081, 0x2082, 0x2082, X 0x1084, 0x0c98, 0x03e0, 0x0000}; X X#define mmask_width 16 X#define mmask_height 16 Xstatic short mmask_bits[] = { X 0x03e0, 0x0fd8, 0x19b4, 0x218a, X 0x6186, 0x4185, 0xc183, 0xffff, X 0xffff, 0xc183, 0xa182, 0x6186, X 0x5184, 0x2d98, 0x1bf0, 0x07c0}; X X#define dots_width 6 X#define dots_height 6 Xstatic short dots_bits[] = { X 0x0001, 0x0000, 0x0000, 0x0008, X 0x0000, 0x0000}; X X#define bomb1_width 16 X#define bomb1_height 16 Xstatic short bomb1_bits[] = { X 0x0000, 0x0000, 0x0000, 0x0000, X 0x0000, 0x0000, 0x0380, 0x07e0, X 0x0ff0, 0x0ff0, 0x0ff8, 0x1ff8, X 0x1ff8, 0x0ff0, 0x0000, 0x0000}; X X#define bomb2_width 24 X#define bomb2_height 24 Xstatic short bomb2_bits[] = { X 0x0000, 0x0000, 0x0000, 0x0000, X 0x0000, 0x0000, 0x0000, 0x0000, X 0x0000, 0x0000, 0x3c00, 0x005a, X 0xff80, 0x0024, 0xffdc, 0x000d, X 0xffe0, 0x0003, 0xffee, 0x0003, X 0xffe0, 0x0003, 0xffc0, 0x0001, X 0xff80, 0x0000, 0x3f00, 0x0000, X 0x3f00, 0x0000, 0x3f00, 0x0000, X 0x3f00, 0x0000, 0x7f00, 0x0000, X 0x7f80, 0x0000, 0x7f80, 0x0000, X 0x7f80, 0x0000, 0xffc0, 0x0000, X 0x0000, 0x0000, 0x0000, 0x0000}; X X#define bomb3_width 32 X#define bomb3_height 32 Xstatic short bomb3_bits[] = { X 0x0000, 0x000f, 0x1ff0, 0x7ff0, X 0x0000, 0x0000, 0xe2fe, 0x3fa3, X 0xfc00, 0x001f, 0xff3c, 0x007f, X 0xff80, 0x00ff, 0xefc0, 0x01fb, X 0xefc0, 0x01fb, 0xefe0, 0x03fb, X 0xffe0, 0x03ff, 0xffe0, 0x03ff, X 0xfde0, 0x01bf, 0xfbe0, 0x49df, X 0xe782, 0x34e7, 0x1e14, 0x4238, X 0x9fe2, 0x3499, 0xbe40, 0x413d, X 0xfdbe, 0x1edf, 0xf800, 0x011f, X 0xfdfe, 0x7fdf, 0xfc00, 0x001f, X 0xfc00, 0x001f, 0xfc00, 0x003f, X 0xfe00, 0x001f, 0xfe00, 0x003f, X 0xff00, 0x003f, 0xffc0, 0x00ff, X 0xfffc, 0x3fff, 0xfffe, 0x7fff, X 0x0000, 0x0000, 0x0000, 0x0000}; END_OF_bitmaps.h if test 2639 -ne `wc -c <bitmaps.h`; then echo shar: \"bitmaps.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f greek.u -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"greek.u\" else echo shar: Extracting \"greek.u\" \(6012 characters\) sed "s/^X//" >greek.u <<'END_OF_greek.u' Xbegin 644 greek.onx XM&````/`'$``!````?@#X#P``"P`!`!``__\````````````````````````` XM```````````````````````````````````````````````````````````` XM`````/]__W_4Z@`````````````!@0`````!`0`````````````````````` XM```````````````````````````````````````````````````````````` XM``````````````0```````````````````````````!551`(```````````` XM```````````````````````````````````````````````````````````` XM````````B8#__P`````````````````````````````````````````````` XM````````````````````````````````````````````@V"!0*UI```````` XM``````)!`````(*"````(`!``'``<`!0`'``8``````````````````````` XM`````````,`````````````0````````````````````0```````#``````` XM`````````````````````"``$`@````````````````````````````````` XM```````````````````````````````````````````````"4`/````````` XM```````````````````````````````````````````````````````````` XM``````````````````````"%4(%`5K<`````````````!"'_#P``?'P```!0 XM`$``0`!``%``$``0``````````````````````````"`````P``````````` XM`-`"``````````````````"@`0`````<```````````````````````````` XM=548&``````````````````````````````````````````````````````` XM`````````````````````````%0%`\`````````````````````````````` XM```````````````````````````````````````````````````````````` XM`(E(@4"]W0`````````````($0```````````%``0`!P`&``<`!P`'`````` XM`````````````````````)@!``!`$```````````V`8````````````````` XM`)`!`````#P`@`0```````````````````````#X@#@\```````````````` XM```````````````````````````````````````````````````````````` XM`````5$#P``````````````````````````````````````````````````` XM````````````````````````````````````````D42!0'=W```````````` XM`!`)`_\``!`0@`$`4`!``!``0`!``$``4````````````````````````(`! XMF`*``,`[``````````#(!P``````````````````B!@`````>`"``P`````` XM`````````````````/W3.#P````````````````````````````````````` XM``````````````````````````````````````````!4"0/````````````` XM```````````````````````````````````````````````````````````` XM``````````````````"A0H%`W=T`````````````(`4`````*"A@!@`@`$`` XM<`!P`$``<``@````````````````````````8`:(`N`#P#P``#@``````.P/ XM``````````````````#4/0````#``.``````````````````````````S\<X XM/``````````````````````````````````````````````````````````` XM`````````````````````"!%`\`````````````````````````````````` XM`````````````````````````````````````````````````````````,%! XM@4"W=@````````````!``_P_``#'QQ@8```````````````````````````` XM```````````````8&/P'@`#`;@``_`\`````_`\``````````````````.(_ XM`````(`!D`````````````````````````!7?SP\```````````````````` XM```````````````````````````````````````````````````````````` XM11,#P``````````````````````````````````````````````````````` XM````````````````````````````````````_W__?_W;```````````&8(`! XM````````Q",```````````````````````````````````````````9@W!^` XM`/!/``#T'P````#>#P``````````````````@!D```````>````````````` XM`````````````(,^?#P````````````````````````````````````````` XM``````````````````````````````````````"0`0/````````````````` XM```````````````````````````````````````````````````````````` XM``````````````#!08%`5G<``````````+9M__\/_````0%$(@`````````` XM````````````````````````````````__^X!/P__`\``/P_`````,(.```` XM``````````````"``0````#X'X``````````````````````````55U\?@`` XM```````````````````````````````````````````````````````````` XM`````````````````,_]`\`````````````````````````````````````` XM`````````````````````````````````````````````````````*%"@4#O XMO0``````````_G]``P````""@D0B```````````````````````````````` XM``````````!F9I@"^'_Z'P``[#\`````PP0``````````````````(`!```` XM`!@=_S\````````````````````````J^'Q^```````````````````````` XM``````````````````````````````````````````````````````````,# XMP``````````````````````````````````````````````````````````` XM````````````````````````````````D42!0+;K``````````#^?R`%_N<` XM`'Q\1"(``````````````````````````````````````````&9FG`(0$?0X XM``#$/P````#A!0``````````````````P`(`````F!S^/P`````````````` XM`````````%_E?GX````````````````````````````````````````````` XM```````````````````````````````````D%0/````````````````````` XM```````````````````````````````````````````````````````````` XM``````````")2(%`IFL``````````+Y_$`D```````#\/P`````````````` XM````````````````````````````9F:4`8@(8B@``,0P`````"$!```````` XM``````````!``@````!8./S_````````````````````````/_#^?@`````` XM```````````````````````````````````````````````````````````` XM`````````````)%(`\`````````````````````````````````````````` XM`````````````````````````````````````````````````(50@4"F:0`` XM````````OG\($?P#```0$``````````````````````````````````````` XM``````!F9K8```"T)```Q#``````,`$``````````````````"`$`````#Q\ XM)`D```````````````````````#UO_Y^```````````````````````````` XM````````````````````````````````````````````````````*!$#P``` XM```````````````````````````````````````````````````````````` XM````````````````````````````@V"!0*9I``````````````0A`````"@H XM`````````````````````````````````````````````&9F(@```)`4``#" XM,``````0`0``````````````````8`P`````_O^2!``````````````````` XM`````.@<_O\````````````````````````````````````````````````` XM```````````````````````````````%!?__```````````````````````` XM```````````````````````````````````````````````````````````` XM``````#_?_]_AF$``````````````D&/CP``Q\<````````````````````` XM````````````````````````__]F````(`$``,`P`````!@#```````````` XM```````````````<.```````````````````````````U5___P`````````` XM```````````````````````````````````````````````````````````` XM`````````$I!__\````````````````````````````````````````````` XM``````````````````````````````````````````````````"&80`````` XM```````!@0`````````````````````````````````````````````````` XM```````````````````````````````````````````````````````````` XM```````````````````````"(?__```````````````````````````````` XM`````````````````````````````````````````````````94``!``(``P XM`$``4`!@`'``@`"0`*``L`#``-``X`#P```!$`$@`3`!0`%0`6`!<`&``9`! XMH`&P`<`!T`'@`?`!``(0`B`",`)``E`"8`)P`H`"D`*@`K`"P`+0`N`"\`(` XM`Q`#(`,P`T`#4`-@`W`#@`.0`Z`#L`/``]`#X`/P`P`$$`0@!#`$0`10!&`$ XM<`2`!)`$H`2P!,`$T`3@!/`$``40!2`%,`5`!5`%8`5P!8`%D`6@!;`%P`70 XM!>`%\`4`!A`&(`8P!D`&4`9@!G`&@`:0!J`&L`;`!M`&X`;P!@`'$`<@!S`' X80`=0!V`'<`>`!Y`'H`>P!\`'T`?@!_`' X` Xend END_OF_greek.u if test 6012 -ne `wc -c <greek.u`; then echo shar: \"greek.u\" unpacked with wrong size! fi # end of overwriting check fi if test -f init.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"init.c\" else echo shar: Extracting \"init.c\" \(6315 characters\) sed "s/^X//" >init.c <<'END_OF_init.c' X/* Copyright (c) 1987 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: init.c,v 1.5 87/06/08 21:45:27 shebs Exp $ */ X X#include "xconq.h" X X/* This is the character used to separate city name from side name in */ X/* predefined maps. So far as I know, no city or people in the world */ X/* has a '*' in the name, so we're pretty safe with this choice. */ X X#define SEPCHAR '*' X Xchar citybuf[MAXCITYBUF]; /* Storage for names of cities and sides */ X X/* Set up some random cache-type variables - probably worthless. */ X/* Also start out in movement mode. */ X Xinit_vars() X{ X int i; X X for (i = 0; i < numutypes; ++i) { X unitchars[i] = utypes[i].uchar; X unitnames[i] = utypes[i].name; X } X for (i = 0; i < numctypes; ++i) { X citychars[i] = ctypes[i].cchar; X citynames[i] = ctypes[i].name; X } X mode = MOVE; X} X X/* This initialization is for NEW games being set up on either a predefined */ X/* or just-generated map. (new maps having names in /tmp probably) */ X Xinit_game() X{ X bool gotmap = FALSE; X char *name, *sname, *next; X int i, x, y, size; X City *city; X Side *side; X X gotmap = read_named_map(TRUE); X if (!gotmap) exit(1); X X /* now make a list of all the cities on the map */ X X numcities = 0; X name = citybuf; X for (y = worldheight-1; y >= 0; --y) { X for (x = 0; x < worldwidth; ++x) { X if (is_urban(x, y)) { X next = (char *) index(name,'\0'); X sname = (char *) index(name, SEPCHAR); X if (sname != NULL) *sname++ = '\0'; X size = urb(x, y); X city = create_city(size, x, y, name, sname, X NOTHING, 0, ctypes[size].hp, numcities++); X if (city == NULL) exit(1); X while (*next++ == '\0'); X name = next-1; X } X } X } X if (numcities < numsides) { X fprintf(stderr, "%d cities not enough for %d sides\n", X numcities, numsides); X exit(1); X } X if (Debug) printf("Created %d cities\n", numcities); X for (i = 0; i < numsides; ++i) { X city = random_start_city(); X side = create_side(humans[i], hosts[i], city->sname, X avgstrat, 0, MINMORALE, 0, FALSE); X city_changes_side(city, side, CAPTURED); X set_product(city, 0, TRUE); X side->morale = SATISFIED; X update_view(side, city->x, city->y); X } X gametime = 0; X} X X/* Initialization related specifically to setting up the world map. */ X X/* Read a map out of a file and push it into an array in the internal format */ X/* Also get all the names of cities but just buffer them up */ X/* Cities and towns are assumed to sit on open land. */ X Xread_world(fp, getcities) XFILE *fp; Xbool getcities; X{ X char ch, maptype; X int i, x, y, terr, ctype; X X fscanf(fp, "%c %d %d %d %d %d\n", X &maptype, &worldwidth, &worldheight, &greenwich, &equator, &scale); X if (worldwidth > MAXWIDTH || worldheight > MAXHEIGHT) { X fprintf(stderr, "%dx%d map too big\n", worldwidth, worldheight); X exit(1); X } X if (worldwidth < 35 || worldheight < 35) { X fprintf(stderr, "%dx%d map too small\n", worldwidth, worldheight); X exit(1); X } X for (y = worldheight-1; y >= 0; --y) { X for (x = 0; x < worldwidth; ++x) { X fscanf(fp, "%c", &ch); X terr = iindex(ch, terrchars); X if (terr < 0) terr = OPEN; X ctype = iindex(ch, citychars); X if (ctype < 0 || !getcities) ctype = RURAL; X set_square(x, y, terr, ctype); X } X fscanf(fp, "\n"); X } X if (getcities) { X /* suck in the rest of the file and stash */ X i = 0; X while ((ch = getc(fp)) != EOF) { X if (ch == ' ' || ch == '\n' || ch == '\t') ch = '\0'; X if (ch == '\\') ch = getc(fp); X citybuf[i++] = ch; X } X citybuf[i++] = '\0'; /* in case somebody forgot a newline at EOF */ X } X if (Debug) printf("Finished creating map\n"); X} X X/* A save file may either be an ordinary file in the current directory, */ X/* or a scenario in the library directory. Look for both. */ X Xrestore_game() X{ X FILE *fp; X X if ((fp = fopen(rawsavename, "r")) != NULL) { X printf("Restoring from %s ...\n", rawsavename); X restore_game_aux(fp); X fclose(fp); X#ifdef UNIX X unlink(rawsavename); X#endif UNIX X return TRUE; X } else if ((fp = fopen(savename, "r")) != NULL) { X printf("Restoring from %s ...\n", savename); X restore_game_aux(fp); X fclose(fp); X /* don't delete the scenarios! */ X return TRUE; X } else { X if (Debug) printf("`%s' not found...\n", savename); X return FALSE; X } X} X X/* This reads in the data proper, taking care to override saved displays */ X/* and player types with anything that was on the command line. */ X Xrestore_game_aux(fp) XFILE *fp; X{ X int gorydetails; X char filetype, terr; X int i, x, y; X X fscanf(fp, "%c %d %d\n", X &filetype, &gametime, &gorydetails); X if (filetype == 'S') { X fgets(rawmapname, BUFSIZE-1, fp); X rawmapname[strlen(rawmapname)-1] = '\0'; X make_lib_pathname(rawmapname, "map", mapname); X read_named_map(FALSE); X } else { X fscanf(fp, "M %d %d %d %d\n", X &worldwidth, &worldheight, &greenwich, &equator); X for (y = 0; y < worldheight; ++y) { X for (x = 0; x < worldwidth; ++x) { X fscanf(fp, "%c", &terr); X set_square(x, y, iindex(terr, terrchars), RURAL); X fscanf(fp, "\n"); X } X } X } X fscanf(fp, "Sides %d %d\n", &numsides, &numhosts); X for (i = 0; i < numsides; ++i) { X if (i < numgivens) { X restore_side(fp, gorydetails, TRUE, humans[i], hosts[i]); X } else { X restore_side(fp, gorydetails, FALSE, FALSE, NULL); X } X } X fscanf(fp, "Cities %d\n", &numcities); X for (i = 0; i < numcities; ++i) { X restore_city(fp); X } X fscanf(fp, "Units %d %d\n", &numunits, &nextid); X for (i = 0; i < numunits; ++i) { X restore_unit(fp); X } X} X X/* Abstraction to read a map given a name of the file. */ X Xread_named_map(getcities) Xbool getcities; X{ X FILE *fp; X X if ((fp = fopen(mapname, "r")) != NULL) { X read_world(fp, getcities); X fclose(fp); X return TRUE; X } else { X#ifdef EXPERIMENTING X if ((fp = fopen(rawmapname, "r")) != NULL) { X read_world(fp, getcities); X fclose(fp); X return TRUE; X } else { X fprintf(stderr, "Can't open map files named '%s' or '%s'\n", X mapname, rawmapname); X exit(1); X } X#endif EXPERIMENTING X fprintf(stderr, "Can't open map file named '%s'\n", mapname); X } X return FALSE; X} END_OF_init.c if test 6315 -ne `wc -c <init.c`; then echo shar: \"init.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f input.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"input.c\" else echo shar: Extracting \"input.c\" \(9936 characters\) sed "s/^X//" >input.c <<'END_OF_input.c' X/* Copyright (c) 1987 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: input.c,v 1.5 87/06/08 21:45:50 shebs Exp $ */ X X#include "xconq.h" X Xint itertime = 100; /* default time for repetition */ X X/* the following structure is used for the dispatch table. */ X Xstruct func_tab { X char f_char; /* character to match against */ X int (*f_func)(); /* pointer to command's function */ X int f_default; /* default repetition */ X char *f_doc; /* short documentation string */ X}; X X/* Movement handled differently, to reduce size/complexity of table lookup. */ X Xchar hjklmoves[] = "kulnjbhy"; X X/* Predeclarations of all commands. */ X Xint do_sentry(), do_random(), do_wakeup(), do_wakeall(), do_embark(), X do_exit(), do_exit_self(), do_message(), do_follow(), X do_redraw(), do_disperse(), do_viewall(), do_return(); X do_sit(), do_product(), do_idle(), do_help(), do_version(), X do_save(), do_standing(), do_ident(), do_moveto(), do_coast(), X do_construct(), do_survey_mode(), do_unit_info(), do_period_dump(); X X/* Dummy to use to make blank lines in cmd display. (what a frob) */ X Xdo_dummy() {} X X/* The command table itself. Note that although blank appears several times */ X/* its real command is in the first occurrence, so everything works out. */ X/* Default iterations of -1 actually turn into whatever the standard default */ X/* is, might have been changed by player. */ X Xstruct func_tab cmdtab[] = { X 's', do_sentry, -1, "put a unit on sentry duty", X 'w', do_wakeup, 1, "wake unit up from whatever it was doing", X ' ', do_sit, 1, "(Space Bar) make unit be on sentry this turn only", X 'm', do_moveto, 1, "move to given location", X 'r', do_return, 1, "return unit to nearest city or transport", X 'c', do_construct, 1, "construct a base", X 'd', do_disperse, 1, "disband unit and send it home", X 'e', do_embark, 1, "embark units in city onto transport in that city", X 'f', do_follow, -1, "follow a designated leader", X 'z', do_survey_mode, 1, "toggle between survey and move modes", X ' ', do_dummy, 1, "", X 'P', do_product, 1, "set/change city production", X 'I', do_idle, -1, "set city to not produce anything", X 'O', do_standing, 1, "set standing orders for units in city", X 'F', do_coast, -1, "follow a coastline", X 'R', do_random, -1, "move unit randomly", X 'W', do_wakeall, 1, "wake up ALL units", X 'M', do_message, 1, "send a message to another side", X 'X', do_exit_self, 1, "resign from the game", X 'Q', do_exit, 1, "kill game for all players", X 'S', do_save, 1, "save game", X ' ', do_dummy, 1, "", X '?', do_help, 1, "show help info", X '/', do_ident, 1, "identify things on screen", X '=', do_unit_info, 1, "display details about unit type", X '+', do_period_dump, 1, "run all parameters into a file", X 'V', do_version, 1, "display program version", X '\014', do_redraw, 1, "(^L) redraw screen", X '\022', do_redraw, 1, "(^R) redraw screen", X#ifdef DEBUGGING X 'v', do_viewall, 1, "look at everything", X#endif DEBUGGING X 0,0,0,0,0,0,0,0 /* paranoia padding */ X}; X X/* Acquire a command from the player. Command may be prefixed with a number */ X/* which is given as an argument to the command function (otherwise arg */ X/* defaults to value in third column of command table). This routine takes */ X/* in both keyboard and mouse input, this is the place to handle other kinds */ X/* of devices also. */ X/* This routine also checks on the number of commands that a player is */ X/* allowed to put in each turn. */ X Xread_command() X{ X char ch; X int inp, x, y, n = -1, dir = -1; X X if ((usecount && countedout) || (usetimer && timedout)) { X if (mode == SURVEY) mode = MOVE; X do_sit(1); X return; X } X /* acquire a parameter in n, otherwise leave it negative for later */ X while ((inp = get_input(&ch, &x, &y)) == KEYBOARD && isdigit(ch)) { X n = (n < 0) ? ch-'0' : n*10 + ch-'0'; X } X if (inp == KEYBOARD) { X if ((dir = iindex(ch, hjklmoves)) >= 0) { X if (n < 0) n = 1; X do_dir(dir, n); X } else if ((dir = iindex(tolower(ch), hjklmoves)) >= 0) { X if (n == itertime && mode == SURVEY) n = 10; X if (n < 0) n = itertime; X do_dir(dir, n); X } else { X execute_command(ch, n); X } X } else if (inp == MOUSE) { X if (x == curx && y == cury) { X do_sit(1); X } else if (abs(curx-x) <= 1 && abs(cury-y) <= 1) { X do_dir(find_dir(x-curx, y-cury), 1); X } else { X switch (mode) { X case MOVE: X order_moveto(curunit, x, y); X break; X case SURVEY: X move_survey(x-curx, y-cury); X break; X default: X case_panic("mode", mode); X } X } X } else { X case_panic("input type", inp); X } X if (usecount) { X --numinputs; X update_count(curside); X if (numinputs <= 0) { X countedout = TRUE; X notify(curside, "No more orders this turn!"); X beep(curside); X } X } X} X X/* Search in command table and execute function if found */ X Xexecute_command(ch, n) Xchar ch; Xint n; X{ X struct func_tab *cmdentry; X X cmdentry = cmdtab; X while (cmdentry->f_char) { X if (ch == cmdentry->f_char) { X if (n < 0) n = cmdentry->f_default; /* try default */ X if (n < 0) n = itertime; X (*(cmdentry->f_func))(n); /* do it!! */ X return; X } X ++cmdentry; X } X notify(curside, "Unknown command '%c'", ch); X} X X/* Get a type of a unit from the player */ X Xread_unit_type(prompt) Xchar *prompt; X{ X char ch; X int inp, x, y, type; X X while (TRUE) { X clear_prompt(curside); X sprintf(curside->promptbuf, "%s [%s] ", prompt, unitchars); X show_prompt(curside); X draw_cursor(curside, curx, cury); X inp = get_input(&ch, &x, &y); X if (inp == KEYBOARD) { X echo_at_prompt(ch); X if (islower(ch)) ch = toupper(ch); X if (ch == '?') { X help_unit_type(); X continue; X } else if ((type = iindex(ch, unitchars)) == -1) { X clear_prompt(curside); X sprintf(curside->promptbuf, "Unit type '%c' not in '%s'", X ch, unitchars); X show_prompt(curside); X flush_output(); X sleep(1); X } else { X break; X } X } X } X clear_prompt(curside); X flush_output(); X return type; X} X X/* User picks a position on map */ X Xread_position(prompt, xp, yp) Xchar *prompt; Xint *xp, *yp; X{ X char ch; X int inp, oldx, oldy; X X oldx = curx; oldy = cury; X X sprintf(curside->promptbuf, "%s [mouse to move, hit key to place] ", X prompt); X show_prompt(curside); X while ((inp = get_input(&ch, xp, yp)) == MOUSE) { X put_on_screen(curside, *xp, *yp); X draw_cursor(curside, *xp, *yp); X } X curx = oldx; cury = oldy; X clear_prompt(curside); X redraw(curside); X} X X/* Get a number from the user */ X Xread_number(prompt, deflt) Xchar *prompt; Xint deflt; X{ X char ch; X int inp, x, y, n; X X sprintf(curside->promptbuf, "%s: [default %d]", prompt, deflt); X show_prompt(curside); X n = 0; X while ((inp = get_input(&ch, &x, &y)) == KEYBOARD && isdigit(ch)) { X echo_at_prompt(ch); X n = n*10 + ch-'0'; X } X if (n == 0) n = deflt; X clear_prompt(curside); X return n; X} X X/* Get a direction from user. The general scheme is to get a moused point, */ X/* then limit the deltas to [-1,1]. This makes it harder to get 0 delta */ X/* values, but that's OK. */ X Xread_direction(prompt) Xchar *prompt; X{ X char ch; X int inp, x, y, dir; X X sprintf(curside->promptbuf, "%s [mouse the direction] ", prompt); X show_prompt(curside); X while ((inp = get_input(&ch, &x, &y)) == KEYBOARD) { X } X clear_prompt(curside); X return find_dir(x - curx, y - cury); X} X X/* Get a type of order */ X Xread_order_type(prompt) Xchar *prompt; X{ X char ch; X int inp, type, x, y; X X while (TRUE) { X clear_prompt(curside); X sprintf(curside->promptbuf, "%s [%s] ", prompt, orderchars); X show_prompt(curside); X draw_cursor(curside, curx, cury); X inp = get_input(&ch, &x, &y); X if (inp == KEYBOARD) { X echo_at_prompt(ch); X if (ch == '?') { X help_order_type(); X continue; X } else if ((type = iindex(tolower(ch), orderchars)) == -1) { X clear_prompt(curside); X sprintf(curside->promptbuf, "Order type '%c' not in '%s'", X ch, orderchars); X show_prompt(curside); X flush_output(); X sleep(1); X } else { X break; X } X } X } X clear_prompt(curside); X flush_output(); X return type; X} X X/* read a message string */ X Xchar msgbuf[BUFSIZE]; X Xchar * Xread_message(toside) XSide *toside; X{ X char ch; X int inp, x, y, i; X X sprintf(curside->promptbuf, "Say to the %s: ", plural_form(toside->name)); X show_prompt(curside); X i = 0; X while ((inp = get_input(&ch, &x, &y)) == KEYBOARD && X ch != '\n' && ch != '\r' && i < BUFSIZE-1) { X echo_at_prompt(ch); X if (ch == '\010') { X if (i >= 0) --i; X } else { X msgbuf[i++] = ch; X } X } X msgbuf[i] = '\0'; X clear_prompt(curside); X flush_output(); X return msgbuf; X} X X/* Help for the main command mode just dumps part of the table, and a little */ X/* extra info about what's not in the table. */ X Xcommand_help() X{ X struct func_tab *cmdentry; X X wprintf(curside, "To move a unit, use the mouse or [hjklyubn]"); X wprintf(curside, "[HJKLYUBN] moves repeatedly in that direction"); X wprintf(curside, "Mousing unit makes it sit, mousing city or unit"); X wprintf(curside, "initiates attack."); X wprintf(curside, " "); X cmdentry = cmdtab; X while (cmdentry->f_char) { X wprintf(curside, "%c %s", cmdentry->f_char, cmdentry->f_doc); X ++cmdentry; X } X} X X/* Predicate to verify that some side wants to do something irreversible. */ X/* This should never be called for machine-played sides. */ X Xconfirm_choice(side, question) XSide *side; Xchar *question; X{ X char ch; X int inp, x, y; X X sprintf(side->promptbuf, "%s [ny]", question); X show_prompt(side); X inp = get_input(&ch, &x, &y); X clear_prompt(side); X if (inp == KEYBOARD && (ch == 'Y' || ch == 'y')) { X return TRUE; X } else { X redraw(side); X return FALSE; X } X} END_OF_input.c if test 9936 -ne `wc -c <input.c`; then echo shar: \"input.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f output.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"output.c\" else echo shar: Extracting \"output.c\" \(9556 characters\) sed "s/^X//" >output.c <<'END_OF_output.c' X/* Copyright (c) 1987 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: output.c,v 1.4 87/06/08 21:45:22 shebs Exp $ */ X X#include "xconq.h" X Xchar *modenames[] = MODENAMES; /* names of the modes */ X X/* Only defined/used here, so no defs in global file. */ X Xchar *moralenames[] = { "Rebellious", "Seditious", "Disaffected", "Weary", X "Bored", "Satisfied", "Supportive", "Enthusiastic", X "Militant", "Fanatical" }; X X/* The current column to insert at on the prompt line (where oh where is */ X/* a good X toolkit?) */ X Xint promptcol; X X/* Variables for the "window printf" utility */ X Xbool wprintmode; /* true when printing is going into a file */ X Xchar wbuf[BUFSIZE]; /* accumulated line of text */ X Xint wcol, wline; /* current position of output */ X XFILE *wfp; /* file pointer for wprintf in file writing mode */ X X/* Send a message to everybody who's got a screen. */ X Xnotify_all(control, a1, a2, a3, a4, a5, a6) Xchar *control, *a1, *a2, *a3, *a4, *a5, *a6; X{ X Side *side; X X for_all_sides(side) { X notify(side, control, a1, a2, a3, a4, a5, a6); X } X} X X#ifdef XWINDOWS X X/* Main message-sending routine - does its own formatting and spits out to */ X/* the given side. */ X Xnotify(side, control, a1, a2, a3, a4, a5, a6) XSide *side; Xchar *control, *a1, *a2, *a3, *a4, *a5, *a6; X{ X char tmpnote[BUFSIZE], notice[BUFSIZE]; X int i; X X if (active_display(side)) { X sprintf(tmpnote, control, a1, a2, a3, a4, a5, a6); X if (islower(tmpnote[0])) tmpnote[0] = toupper(tmpnote[0]); X sprintf(notice, "%d: %s", gametime, tmpnote); X for (i = 1; i < MAXNOTES; ++i) { X strcpy(side->noticebuf[i-1], side->noticebuf[i]); X } X strcpy(side->noticebuf[MAXNOTES-1], notice); X show_note(side); X XFlush(); X if (Debug) printf("%s\n", notice); X } X} X X/* Notice area refresher. All notes except the most recent one are grayed */ X/* out. */ X Xshow_note(side) XSide *side; X{ X int i; X X XClear(side->msg); X for (i = 0; i < MAXNOTES; ++i) { X XText(side->msg, 0, i*fh, X side->noticebuf[i], strlen(side->noticebuf[i]), X side->msgfont, X (i == MAXNOTES-1) ? side->fgcolor : side->graycolor, X side->bgcolor); X } X} X X/* Management of current unit/city info. */ X Xset_current_info(side, str1, str2) XSide *side; Xchar *str1, *str2; X{ X strcpy(side->infobuf[0], str1); X strcpy(side->infobuf[1], str2); X} X X/* Refreshes info lines. */ X Xshow_info(side) XSide *side; X{ X if (active_display(side)) { X XClear(side->info); X XText(side->info, 0, 0*fh, side->infobuf[0], strlen(side->infobuf[0]), X side->msgfont, side->fgcolor, side->bgcolor); X XText(side->info, 0, 1*fh, side->infobuf[1], strlen(side->infobuf[1]), X side->msgfont, side->fgcolor, side->bgcolor); X XFlush(); X } X} X X/* Erase info stuff. Hit the arrays so we don't get annoyed when old and */ X/* worthless info reappears upon redraw. */ X Xclear_info (side) XSide *side; X{ X if (active_display(side)) { X sprintf(side->infobuf[0], " "); X sprintf(side->infobuf[1], " "); X XClear(side->info); X } X} X X/* The prompt window consists of exactly one line, but we have to keep track */ X/* of where the blank space begins, for when people type into it. */ X Xshow_prompt(side) XSide *side; X{ X if (active_display(side)) { X XText(side->prompt, 0, 0, side->promptbuf, strlen(side->promptbuf), X side->msgfont, side->fgcolor, side->bgcolor); X promptcol = strlen(side->promptbuf) + 1; X } X} X X/* Spit a char onto the prompt line, hopefully after the previous one. */ X/* Kludge to handle backspaces, should be fixed, or else use toolkit... */ X Xecho_at_prompt(ch) Xchar ch; X{ X char tmp[2]; X X /* no display test needed ... */ X X if (ch == '\010') { X tmp[0] = ' '; X XText(curside->prompt, (--promptcol)*fw, 0, tmp, 1, X curside->msgfont, curside->fgcolor, curside->bgcolor); X } else { X tmp[0] = ch; X XText(curside->prompt, (promptcol++)*fw, 0, tmp, 1, X curside->msgfont, curside->fgcolor, curside->bgcolor); X } X XFlush(); X} X X/* Clear the prompt line. We only call this when no display test needed. */ X Xclear_prompt(side) XSide *side; X{ X sprintf(side->promptbuf, " "); X XClear(side->prompt); X} X X/* Update the turn number display. */ X Xshow_time(side) XSide *side; X{ X char timebuf[BUFSIZE]; X X if (active_display(side)) { X XClear(side->time); X sprintf(timebuf, "Turn %4d", gametime); X XText(side->time, 0, 0, timebuf, strlen(timebuf), X side->msgfont, side->fgcolor, side->bgcolor); X XFlush(); X if (Debug) printf("Turn %d\n", gametime); X } X} X X/* Update the Mode display. */ X Xshow_mode(side) XSide *side; X{ X char modebuf[BUFSIZE]; X X if (active_display(side)) { X XClear(side->mode); X sprintf(modebuf, "%s Mode", modenames[mode]); X XText(side->mode, 0, 0, modebuf, strlen(modebuf), X side->msgfont, side->fgcolor, side->bgcolor); X XFlush(); X } X} X X/* Update the State display (random global things about a side). */ X/* So far this includes morale and the number of inputs remaining that turn. */ X Xshow_state(side) XSide *side; X{ X char statebuf[BUFSIZE]; X X if (active_display(side)) { X XClear(side->state); X sprintf(statebuf, "Morale %d (%s) Score %d", X side->morale, moralenames[side->morale/1000], side->score); X XText(side->state, 0, 1*fh, statebuf, strlen(statebuf), X side->msgfont, side->fgcolor, side->bgcolor); X if (usecount) { X sprintf(statebuf, "%3d inputs left", numinputs); X XText(side->state, 0, 0*fh, statebuf, strlen(statebuf), X side->msgfont, side->fgcolor, side->bgcolor); X } X XFlush(); X } X} X X/* Tweak the counter only (probably a bogus optimization) */ X Xupdate_count(side) XSide *side; X{ X char tmp[BUFSIZE]; X X if (active_display(side)) { X sprintf(tmp, "%3d", numinputs); X XText(side->state, 0, 0, tmp, strlen(tmp), X side->msgfont, side->fgcolor, side->bgcolor); X XFlush(); X } X} X X/* Show a list of all sides in action, drawing a line through any that have */ X/* lost out. */ X Xshow_all_sides(side) XSide *side; X{ X int midhgt; X Side *side2; X X if (active_display(side)) { X XClear(side->sides); X for_all_sides(side2) { X XText(side->sides, 0, side_number(side2)*fh, X side2->titlebuf, strlen(side2->titlebuf), X side->msgfont, side->graycolor, side->bgcolor); X if (side2->lost) { X midhgt = side_number(side2)*fh+fh/2; X XLine(side->sides, 0, midhgt, 500, midhgt, X 1, 1, side->graycolor, GXcopy, AllPlanes); X } X } X XFlush(); X } X} X X/* Highlight the side whose turn it is, using reverse video for current */ X/* player's own display (to wake she/he/it up) and white instead of gray */ X/* for everybody else. */ X Xshow_curside(side) XSide *side; X{ X if (active_display(side) && curside != NULL) { X XText(side->sides, 0, side_number(curside)*fh, X curside->titlebuf, strlen(curside->titlebuf), side->msgfont, X (side == curside ? side->bgcolor : side->fgcolor), X (side == curside ? side->fgcolor : side->bgcolor)); X XFlush(); X } X} X X/* Un-highlight the side whose turn it no longer is. */ X Xunshow_curside(side) XSide *side; X{ X if (active_display(side) && curside != NULL) { X XText(side->sides, 0, side_number(curside)*fh, X curside->titlebuf, strlen(curside->titlebuf), X side->msgfont, side->graycolor, side->bgcolor); X XFlush(); X } X} X X/* Update the countdown timer window. */ X Xshow_countdown(side) XSide *side; X{ X char clockbuf[BUFSIZE]; X X if (active_display(side)) { X XClear(side->clock); X sprintf(clockbuf, "%3d", countdown); X XText(side->clock, 0, 0, clockbuf, strlen(clockbuf), X side->msgfont, side->fgcolor, side->bgcolor); X XFlush(); X } X} X X/* beep the beeper! */ X Xbeep(side) XSide *side; X{ X if (active_display(side)) XFeep(0); X} X X/* Dump a file into the help window. This routine is neither sophisticated */ X/* nor robust - lines must be short enough and file must be one page. */ X/* Returns success or failure of file opening. */ X Xshow_file(side, fname) XSide *side; Xchar *fname; X{ X FILE *fp; X X if ((fp = fopen(fname, "r")) != NULL) { X while (fgets(spbuf, BUFSIZE, fp)) { X spbuf[strlen(spbuf)-1] = '\0'; /* cut off newline */ X wprintf(side, spbuf); X } X fclose(fp); X return TRUE; X } else { X return FALSE; X } X} X X/* Little routines to pop up the help window and make it go away again */ X/* They only get called when display is in use */ X XWindow tmphelp; X Xreveal_help() X{ X tmphelp = curside->help; X X XMapWindow(tmphelp); X XClear(tmphelp); X} X Xconceal_help() X{ X XUnmapWindow(tmphelp); X redraw(curside); X XFlush(); X} X X/* init our counters or open a file. */ X Xinit_wprintf(fname) Xchar *fname; X{ X wcol = 0; X wline = 0; X wprintmode = (fname != NULL); X if (wprintmode) { X wfp = fopen(fname, "w"); X } X} X X/* Make like printf, but to the help window. This is pretty crude - has an */ X/* automatic newlining (mis)feature, and doesn't do anything about long */ X/* lines, but it's good enough. */ X Xwprintf(side, control, a1, a2, a3, a4, a5, a6) XSide *side; Xchar *control, *a1, *a2, *a3, *a4, *a5, *a6; X{ X sprintf(wbuf, control, a1, a2, a3, a4, a5, a6); X if (wprintmode && wfp != NULL) { X fprintf(wfp, "%s\n", wbuf); X } else { X if (strlen(wbuf) > 0) { X XText(side->help, wcol*fw, wline*fh, wbuf, strlen(wbuf), X side->msgfont, side->fgcolor, side->bgcolor); X } X wline++; /* should acct for newlines etc */ X } X} X X/* If we were actually printing to a file, close it down. */ X Xfinish_wprintf() X{ X if (wprintmode && wfp != NULL) fclose(wfp); X} X X#endif XWINDOWS END_OF_output.c if test 9556 -ne `wc -c <output.c`; then echo shar: \"output.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f side.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"side.c\" else echo shar: Extracting \"side.c\" \(9926 characters\) sed "s/^X//" >side.c <<'END_OF_side.c' X/* Copyright (c) 1987 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: side.c,v 1.5 87/06/07 11:37:07 shebs Exp $ */ X X#include "xconq.h" X X#include "side.h" X XSide sides[MAXSIDES]; /* arrays containing all sides */ XSide *sidelist; /* head of list of all sides */ XSide *curside; /* side whose turn it is right now */ X Xbool snameused[MAXSIDENAMES]; /* flags true if a name of side already used */ X Xint numsides; /* number of sides in the game */ X X/* Reset side array and related things. */ X Xinit_sides() X{ X int i, s; X X for (i = 0; i < MAXSIDENAMES; ++i) { X snameused[i] = FALSE; X } X for (s = 0; s < MAXSIDES; ++s) { X sides[s].name = NULL; X } X sidelist = NULL; X} X X/* Create an object representing a side. Most of the work is picking */ X/* a name, although there's plenty of other inits to do. */ X XSide * Xcreate_side(person, host, name, strategy, basenum, morale, score, lost) Xbool person, lost; Xchar *host, *name; Xint basenum, strategy, morale, score; X{ X unsigned char ch, *tmp; X int s, n, i; X X if (person && host == NULL) { X fprintf(stderr, "Human player with no display!\n"); X abort(); X } X for (s = 0; s < MAXSIDES; ++s) { X if (sides[s].name == NULL) { X sides[s].humanp = person; X if (host != NULL) { X sides[s].host = malloc(strlen(host)+2); X strcpy(sides[s].host, host); X } else sides[s].host = NULL; X#ifdef XWINDOWS X if (name == NULL && host != NULL && X strcmp(host, getenv("DISPLAY")) == 0) { X name = XGetDefault(programname, "SideName"); X } X#endif XWINDOWS X if (name == NULL) { X while (snameused[(n=random(MAXSIDENAMES))]); X snameused[n] = TRUE; X name = sidenames[n]; X } X sides[s].name = malloc(strlen(name)+2); X strcpy(sides[s].name, name); X sprintf(sides[s].titlebuf, X "%d: The %s (%s)", X s, plural_form(sides[s].name), (host != NULL ? host : "")); X for (i = 0; i < numutypes; ++i) { X sides[s].counts[i] = 1; /* reset id# of units */ X } X sides[s].view = (unsigned char *) malloc(worldwidth*worldheight); X tmp = sides[s].view; X for (i = 0; i < worldwidth*worldheight; ++i) *tmp++ = UNSEEN; X sides[s].basenum = basenum; X sides[s].morale = morale; X sides[s].score = score; X sides[s].lost = lost; X sides[s].territory = 1; X sides[s].strategy = strategy; X link_in_side(&sides[s]); X return &sides[s]; X } X } X fprintf(stderr, "Cannot have more than %d sides total\n", MAXSIDES); X abort(); X} X X/* Add the new side to the end of the list of sides - this keeps our */ X/* list traversals going from top to bottom. */ X Xlink_in_side(side) XSide *side; X{ X Side *head, *last; X X if (sidelist == NULL) { X sidelist = side; X } else { X for (head = sidelist; head != NULL; head = head->next) { X if (head->next == NULL) last = head; X } X last->next = side; X } X side->next = NULL; X} X X/* Given a side, get its relative position in array of sides (the "number"). */ X Xside_number(side) XSide *side; X{ X return (side == NULL ? -1 : (side - sides)); X} X X/* The inverse function - given a number, figure out which side it reps. */ X XSide * Xside_n(n) Xint n; X{ X return ((n >= 0 && n < numsides) ? &sides[n] : NULL); X} X X/* Pretty simple for a function, but some day we might want to re-use unit */ X/* numbers and only retire the numbers of the most successful units :-) */ X Xassign_unit_number(type, side) Xint type; XSide *side; X{ X return (side->counts)[type]++; X} X X/* Any effects of morale change should be in here. */ X Xadjust_morale(side, n) XSide *side; Xint n; X{ X if (side == NULL) return; X side->morale += n; X side->morale = max(MINMORALE, min(side->morale, MAXMORALE)); X show_state(side); X} X X/* When size of territory changes, so does morale. When territory is lost, */ X/* morale goes down by 1/3 more than it goes up from a comparable territory */ X/* gain. The people are fickle (also keeps games from dragging out). */ X Xadjust_territory(side, n, changemorale) XSide *side; Xint n, changemorale; X{ X int newterr, newmorale, diff; X X if (side == NULL) return; X newterr = max(1, side->territory + n); X if (changemorale) { X newmorale = (side->morale * newterr) / side->territory; X newmorale = max(500, min(9000, newmorale)); X diff = newmorale - side->morale; X if (diff < 0) diff += diff/3; X adjust_morale(side, diff); X } X side->territory = newterr; X} X Xadjust_score(side, n) XSide *side; Xint n; X{ X if (side == NULL) return; X side->score += n; X show_state(side); X} X X/* Make the whole world be known to all players. */ X Xall_view_world() X{ X int x, y; X Side *side; X X for (side = sidelist; side != NULL; side = side->next) { X for (x = 0; x < worldwidth; ++x) { X for (y = 0; y < worldheight; ++y) { X see_something(side, x, y, FALSE); X } X } X } X} X X/* How things see others. The tricky part of this is handling everybody's */ X/* different points of view at the same time. We start with a side and pos */ X/* and update that sides' view of everything visible from that position. At */ X/* the same time, we update everybody else's view of the that same position, */ X/* being careful to avoid computing views from neutral cities... */ X Xupdate_view(side, x, y) XSide *side; Xint x, y; X{ X int d, x1, y1; X Unit *unit; X City *city; X Side *side2; X X see_something(side, x, y, TRUE); X for (d = 0; d < 8; ++d) { X x1 = wrap(x + dirx[d]); y1 = limit(y + diry[d]); X if ((city = city_at(x1, y1)) != NULL) { X side2 = city->side; X } else if ((unit = unit_at(x1, y1)) != NULL) { X side2 = unit->side; X } else { X side2 = NULL; X } X see_something(side, x1, y1, FALSE); X see_something(side2, x, y, FALSE); X } X} X X/* What the given side sees at the given location, irrespective of whether */ X/* anything sees it or not. */ X Xsee_something(side, x, y, seehidden) XSide *side; Xint x, y, seehidden; X{ X Unit *unit; X City *city; X X if (side == NULL) return; X if ((city = city_at(x, y)) != NULL) { X set_side_view(side, x, y, X buildview(side_number(city->side), VCITY, city->size)); X } else if ((unit = unit_at(x, y)) != NULL && X (seehidden || !(unit->hidden && side != unit->side))) { X set_side_view(side, x, y, X buildview(side_number(unit->side), VUNIT, unit->type)); X } else { X set_side_view(side, x, y, EMPTY); X } X if (active_display(side)) X draw_square(side, x, y); X} X X/* Verbal description of what you can see on the screen (plus city names). */ X Xshow_thing_seen(side, x, y) XSide *side; Xint x, y; X{ X int view; X Side *side2; X X view = side_view(side, x, y); X if (view == EMPTY) { X clear_info(side); X } else { X side2 = side_n(valign(view)); X if (vthing(view) == VCITY) { X sprintf(spbuf, "%s %s of %s", X (side2 == NULL ? "neutral" : side2->name), X citynames[vtype(view)], X (city_at(x, y) ? city_at(x, y)->name : "graves")); X } else { X sprintf(spbuf, "%s %s", X side2->name, unitnames[vtype(view)]); X } X sprintf(spbuf2, ""); X set_current_info(side, spbuf, spbuf2); X } X show_info(side); X draw_cursor(side, x, y); X} X X/* A side can be saved with or without the entire view, which is a fairly */ X/* large sort of thing. Machine sides without displays have their names */ X/* written as ___ - let us hope and pray that such a perverted name never */ X/* appears as a valid X display. */ X Xsave_side(side, fp, gorydetails) XSide *side; XFILE *fp; Xbool gorydetails; X{ X int i, x, y; X X fprintf(fp, "%s\n%s\n%d %d %d %d %d %d ", X side->name, (side->host ? side->host : "___"), X side->humanp, side->strategy, side->basenum, side->morale, X side->score, side->lost); X for (i = 0; i < 3; ++i) { X fprintf(fp, "%d ", side->stratparms[i]); X } X for (i = 0; i < numutypes; ++i) { X fprintf(fp, "%d ", side->counts[i]); X } X fprintf(fp, "\n"); X if (gorydetails) { X for (y = 0; y < worldheight; ++y) { X for (x = 0; x < worldwidth; ++x) { X fprintf(fp, "%d ", side_view(side, x, y)); X } X fprintf(fp, "\n"); X } X } X} X X/* Machine-played sides have to be restored without getting attached to */ X/* displays. */ X Xrestore_side(fp, gorydetails, subst, cmdhuman, cmdhost) XFILE *fp; Xint gorydetails, subst, cmdhuman; Xchar *cmdhost; X{ X char name[BUFSIZE], host[BUFSIZE], *hostptr; X int i, j, x, y, terr, tmp1, hum, strat, bn, mor, score, lost; X Side *side; X X fgets(name, BUFSIZE-1, fp); name[strlen(name)-1] = '\0'; X fgets(host, BUFSIZE-1, fp); host[strlen(host)-1] = '\0'; X fscanf(fp, "%d %d %d %d %d %d", &hum, &strat, &bn, &mor, &score, &lost); X if (strcmp(host, "___") == 0) X hostptr = NULL; X else X hostptr = host; X if (subst) { X hostptr = cmdhost; X hum = cmdhuman; X } X side = create_side(hum, hostptr, name, strat, bn, mor, score, lost); X for (j = 0; j < 3; ++j) { X fscanf(fp, "%d ", &tmp1); X side->stratparms[j] = tmp1; X } X for (j = 0; j < numutypes; ++j) { X fscanf(fp, "%d ", &tmp1); X side->counts[j] = tmp1; X } X if (gorydetails) { X for (y = 0; y < worldheight; ++y) { X for (x = 0; x < worldwidth; ++x) { X fscanf(fp, "%d", &tmp1); X set_side_view(side, x, y, tmp1); X } X } X fscanf(fp, "\n"); X } X if (Debug) printf("Restored side %s (%s)\n", side->name, side->host); X} X X/* Show some overall numbers on performance of a side. */ X Xprint_side_results(fp, side) XFILE *fp; XSide *side; X{ X int ctype; X X fprintf(fp, "%s\n\n", side->titlebuf); X fprintf(fp, X "Production (Time spent on finished products / total time):\n"); X for (ctype = 1; ctype < numctypes; ++ctype) { X if (side->production[ctype] > 0) { X fprintf(fp, "%s %4d / %4d (Efficiency %.2f)\n", X citynames[ctype], X side->completion[ctype], side->production[ctype], X (((float) side->completion[ctype]) / X side->production[ctype])); X } X } X fprintf(fp, "\n"); X} END_OF_side.c if test 9926 -ne `wc -c <side.c`; then echo shar: \"side.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f util.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"util.c\" else echo shar: Extracting \"util.c\" \(6229 characters\) sed "s/^X//" >util.c <<'END_OF_util.c' X/* Copyright (c) 1987 Stanley T. Shebs, University of Utah. */ X/* This program may be used, copied, modified, and redistributed freely */ X/* for noncommercial purposes, so long as this notice remains intact. */ X X/* RCS $Header: util.c,v 1.5 87/06/08 21:45:08 shebs Exp $ */ X X#include "xconq.h" X Xint dirx[] = DIRX, diry[] = DIRY; /* arrays for dir-to-delta conversion */ X X/* Random number handling is important to game but terrible in some Unices. */ X/* These should probably be replaced with homemade routines. */ X Xinit_random() X{ X srand(getpid()); X} X X/* The 37 is a bit of magic inherited from Larry Wall's warp - he had */ X/* observed a rand() producing successive evens and odds. */ X Xrandom(m) X{ X return ((rand() / 37) % m); X} X X/* Different Unices have different favorite ways of making new filenames. */ X Xchar * Xtemp_name() X{ X#ifdef HPUX X return tempnam("/tmp", "xconq"); X#endif HPUX X#ifdef BSD X return (char *) mktemp("/tmp/xconqXXXXXX"); X#endif BSD X} X Xmake_lib_pathname(name, extn, pathbuf) Xchar *name, *extn, *pathbuf; X{ X#ifdef UNIX X sprintf(pathbuf, "%s/%s.%s", XCONQLIB, name, extn); X#endif UNIX X} X X/* True if coords at or outside whole world or restriction of it */ X Xat_world_edge(x, y) Xint x, y; X{ X return (y >= worldheight-1 || y < 1); X} X X/* Are we next to terrain where we can get supplies? */ X Xis_adj_resupply(type, x, y) Xint type, x, y; X{ X int x1, y1; X X for (x1 = x-1; x1 <= x+1; ++x1) X for (y1 = y-1; y1 <= y+1; ++y1) X if (utypes[type].adj[terrain(wrap(x1), y1)]) return TRUE; X return FALSE; X} X Xadj_obstacle(type, x, y) Xint type, x, y; X{ X int x1, y1; X X for (x1 = x-1; x1 <= x+1; ++x1) X for (y1 = y-1; y1 <= y+1; ++y1) X if (utypes[type].moveson[terrain(wrap(x1), y1)] == 0) return TRUE; X return FALSE; X} X Xsurrounded(side, x, y) XSide *side; Xint x, y; X{ X int x1, y1; X X for (x1 = x-1; x1 <= x+1; ++x1) X for (y1 = y-1; y1 <= y+1; ++y1) X if (!(x1 == x && y1 == y) && X friendly_square(side, wrap(x1), limit(y1))) return FALSE; X return TRUE; X} X Xfriendly_square(side, x, y) XSide *side; Xint x, y; X{ X Unit *unit; X City *city; X X if ((unit = unit_at(x, y)) != NULL && side != unit->side) X return FALSE; X if ((city = city_at(x, y)) != NULL && side != city->side) X return FALSE; X return TRUE; X} X X/* Given deltas, compute direction number. */ X Xfind_dir(dx, dy) Xint dx, dy; X{ X if (dx < 0) { X if (dy < 0) return SW; X if (dy == 0) return WEST; X return NW; X } else if (dx == 0) { X if (dy > 0) return NORTH; X if (dy == 0) { fprintf(stderr, "bogus deltas!\n"); abort(); } X return SOUTH; X } else { X if (dy < 0) return SE; X if (dy == 0) return EAST; X return NE; X } X} X X/* Given a number, figure out what suffix should go with it. */ X Xchar ordnum[10]; X Xchar * Xordinal(n) Xint n; X{ X char *suff; X int n1; X X n1 = n % 100; X X if (n1 == 11 || n1 == 12 || n1 == 13) X suff = "th"; X else X switch (n % 10) { X case 1: suff = "st"; break; X case 2: suff = "nd"; break; X case 3: suff = "rd"; break; X default: suff = "th"; break; X } X sprintf(ordnum, "%d%s", n, suff); X return ordnum; X} X Xchar pluralbuf[BUFSIZE]; X Xchar * Xplural_form(word) Xchar *word; X{ X char endch; X X endch = word[strlen(word)-1]; X if (endch == 'h' || endch == 's') X sprintf(pluralbuf, "%s", word); X else X sprintf(pluralbuf, "%ss", word); X return pluralbuf; X} X X/* almost worthless routine to display a useless coordinate pair */ X Xchar posbuf[BUFSIZE]; X Xchar * Xpos_desig(x, y) Xint x, y; X{ X sprintf(posbuf, " (%d,%d)", x - greenwich, y - equator); X return posbuf; X} X X/* get a *numeric* index into a string (infinitely more useful than ptr!) */ X Xiindex(ch, str) Xchar ch, *str; X{ X char *rest; X X return ((rest = (char *) index(str, ch)) == NULL) ? -1 : rest - str; X} X X/* true if there is a unit of given type close by (used by machine strategy) */ X Xadj_unit_type(unit, type, exp, eyp) XUnit *unit; Xint type, *exp, *eyp; X{ X int d, ix, iy; X Unit *other; X X for (d = 0; d < 8; ++d) { X ix = unit->x + dirx[d]; iy = unit->y + diry[d]; X if ((other = unit_at(wrap(ix), iy)) != NULL && X other->side == unit->side && X other->type == type) { X *exp = wrap(ix); *eyp = iy; X return TRUE; X } X } X return FALSE; X} X X/* count up passengers for a given unit */ X Xcargo_size(unit, type) XUnit *unit; Xint type; X{ X int num = 0; X Unit *carg; X X for (carg = unit->cargo; carg != NULL; carg = carg->nexthere) { X if (carg->type == type) ++num; X } X return num; X} X X/* generalized area search routine */ X/* It starts in the immediately adjacent squares and expands outwards */ X/* Always searches in same pattern - hard to change this... */ X Xsearch_area(x0, y0, maxdist, pred, rxp, ryp) Xint x0, y0, maxdist, (*pred)(), *rxp, *ryp; X{ X int x, y, y1, dist; X X for (dist = 1; dist <= maxdist; ++dist) { X if (flip_coin()) { X for (x = x0 - dist; x <= x0 + dist; ++x) { X y1 = limit(y0 - dist); X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X y1 = limit(y0 + dist); X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X } X for (y = y0 - dist; y <= y0 + dist; ++y) { X y1 = limit(y); X x = x0 - dist; X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X x = x0 + dist; X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X } X } else { X for (y = y0 - dist; y <= y0 + dist; ++y) { X y1 = limit(y); X x = x0 - dist; X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X x = x0 + dist; X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X } X for (x = x0 - dist; x <= x0 + dist; ++x) { X y1 = limit(y0 - dist); X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X y1 = limit(y0 + dist); X if ((*pred)(wrap(x), y1)) { X *rxp = wrap(x); *ryp = y1; X return TRUE; X } X } X } X } X return FALSE; X} X X/* This little routine goes at the end of all case statements on internal */ X/* data that shouldn't go out of bounds. */ X Xcase_panic(str, var) Xchar *str; Xint var; X{ X fprintf(stderr, "Panic! Unknown %s %d\n", str, var); X abort(); X} END_OF_util.c if test 6229 -ne `wc -c <util.c`; then echo shar: \"util.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 6 \(of 7\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 7 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0