[comp.sources.games] v10i076: nethack3p9 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 76
Archive-name: nethack3p9/Part31
Supersedes: NetHack3: Volume 7, Issue 56-93



#! /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 31 (of 56)."
# Contents:  auxil/Makefile.auxil src/lev_comp.y src/pri.c
# Wrapped by billr@saab on Wed Jul 11 17:11:38 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'auxil/Makefile.auxil' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'auxil/Makefile.auxil'\"
else
echo shar: Extracting \"'auxil/Makefile.auxil'\" \(1889 characters\)
sed "s/^X//" >'auxil/Makefile.auxil' <<'END_OF_FILE'
X#	NetHack Makefile.
X#	SCCS Id: @(#)Makefile.auxil	3.0	90/05/28
X
XVARAUX = data rumors
XGUIDEBOOK = Guidebook		# regular ASCII file
X#GUIDEBOOK = Guidebook.ps	# PostScript file
X#GUIDEBOOK = Guidebook.dvi	# TeX device-independent file
X
Xall:	$(GUIDEBOOK) $(VARAUX) spec_levs
X
X# The tmac.n macros come with the B news software, which should be available
X# at your friendly local archive site if you don't already have it.
X# An updated version also comes with the Elm mail distribution.
X# They are used here because they are more widely available (if not more
X# widely installed) than various proprietary macro packages that came with
X# your machine but not your neighbor's.
X#
X# If you can't install tmac.n in the appropriate system directory, you
X# can create the processed Guidebook in stages:
X#	tbl Guidebook.mn > Guidebook.tmp
X#	nroff tmac.n Guidebook.tmp | col > Guidebook
X#	rm Guidebook.tmp
X# or simply by saying:
X#	tbl tmac.n Guidebook.mn | nroff | col > Guidebook
XGuidebook:	Guidebook.mn
X	tbl Guidebook.mn | nroff -mn | col > Guidebook
X
X# Fancier output for those with ditroff, psdit and a PostScript printer.
XGuidebook.ps:	Guidebook.mn
X	tbl Guidebook.mn | ditroff -mn | psdit > Guidebook.ps
X
X# Guidebook.tex is the same as Guidebook.mn but formatted with LaTeX.
X# - The invocation command for LaTeX may vary in different installations.
X# - To print Guidebook.dvi you need to use a suitable dvi-driver.
XGuidebook.dvi:	Guidebook.tex
X	latex Guidebook.tex
X
Xdata:	data.base ../src/makedefs
X	( cd ../src ; ./makedefs -d )
X
Xrumors:	rumors.tru rumors.fal ../src/makedefs
X	( cd ../src ; ./makedefs -r )
X
Xspec_levs: castle.des endgame.des tower.des ../src/lev_comp
X	../src/lev_comp castle.des
X	../src/lev_comp endgame.des
X	../src/lev_comp tower.des
X	touch spec_levs
X
Xspotless:
X	-rm -f Guidebook Guidebook.ps Guidebook.dvi Guidebook.aux Guidebook.log data rumors castle endgame tower1 tower2 tower3
END_OF_FILE
if test 1889 -ne `wc -c <'auxil/Makefile.auxil'`; then
    echo shar: \"'auxil/Makefile.auxil'\" unpacked with wrong size!
fi
# end of 'auxil/Makefile.auxil'
fi
if test -f 'src/lev_comp.y' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/lev_comp.y'\"
else
echo shar: Extracting \"'src/lev_comp.y'\" \(24370 characters\)
sed "s/^X//" >'src/lev_comp.y' <<'END_OF_FILE'
X%{ 
X/*	SCCS Id: @(#)lev_comp.c	3.0	90/01/03
X/*	Copyright (c) 1989 by Jean-Christophe Collet */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X * This file contains the Level Compiler code
X * It may handle special mazes & special room-levels
X */
X
X/* block some unused #defines to avoid overloading some cpp's */
X#define MONDATA_H	/* comment line for pre-compiled headers */
X#define MONFLAG_H	/* comment line for pre-compiled headers */
X
X#include "hack.h"
X#include "sp_lev.h"
X#ifndef O_WRONLY
X# include <fcntl.h>
X#endif
X#ifndef O_CREAT	/* some older BSD systems do not define O_CREAT in <fcntl.h> */
X# include <sys/file.h>
X#endif
X
Xvoid FDECL(yyerror, (char *));
Xvoid FDECL(yywarning, (char *));
Xint NDECL(yylex);
Xint NDECL(yyparse);
X
Xint FDECL(get_room_type, (char *));
Xint FDECL(get_trap_type, (char *));
Xint FDECL(get_monster_id, (char *, CHAR_P));
Xint FDECL(get_object_id, (char *, CHAR_P));
Xboolean FDECL(check_monster_char, (CHAR_P));
Xboolean FDECL(check_object_char, (CHAR_P));
Xvoid FDECL(scan_map, (char *));
Xvoid NDECL(store_part);
Xvoid FDECL(write_maze, (int, specialmaze *));
X
X#ifdef AMIGA
Xchar *fgets();
X# undef     fopen
X# undef     printf
X# undef     Printf
X# define    Printf  printf
X#ifndef	LATTICE
X# define    memset(addr,val,len)    setmem(addr,len,val)
X#endif
X#endif
X
X#ifdef MSDOS
X# undef exit
Xextern void FDECL(exit, (int));
X#endif
X
X#ifdef MACOS
X# undef printf
X# undef Printf
X# define Printf printf
X#endif
X
X#undef NULL
X
X#define MAX_REGISTERS	10
X#define ERR		(-1)
X
Xstruct reg {
X	int x1, y1;
X	int x2, y2;
X}		current_region;
X
Xstruct coord {
X	int x;
X	int y;
X}		current_coord;
X
Xstruct {
X	char *name;
X	short type;
X} trap_types[TRAPNUM-1] = {
X	"monster",	MONST_TRAP,
X	"statue",	STATUE_TRAP,
X	"bear",		BEAR_TRAP,
X	"arrow",	ARROW_TRAP,
X	"dart",		DART_TRAP,
X	"trapdoor",	TRAPDOOR,
X	"teleport",	TELEP_TRAP,
X	"pit",		PIT,
X	"sleep gas",	SLP_GAS_TRAP,
X	"magic",	MGTRP,
X	"board",	SQBRD,
X	"web",		WEB,
X	"spiked pit",	SPIKED_PIT,
X	"level teleport",LEVEL_TELEP,
X#ifdef SPELLS
X	"anti magic",	ANTI_MAGIC,
X#endif
X	"rust",		RUST_TRAP
X#ifdef POLYSELF
X	, "polymorph",	POLY_TRAP
X#endif
X#ifdef ARMY
X	, "land mine",	LANDMINE
X#endif
X  };
X
Xstruct {
X	char *name;
X	int type;
X} room_types[SHOPBASE-1] = {
X	/* for historical reasons, room types are not contiguous numbers */
X	/* (type 1 is skipped) */
X	"ordinary",	OROOM,
X#ifdef THRONES
X	"throne",	COURT,
X#endif
X	"swamp",	SWAMP,
X	"vault",	VAULT,
X	"beehive",	BEEHIVE,
X	"morgue",	MORGUE,
X#ifdef ARMY
X	"barracks",	BARRACKS,
X#endif
X	"zoo",		ZOO,
X	"temple",	TEMPLE,
X	"shop",		SHOPBASE,
X};
X
Xshort db_dirs[4] = {
X	DB_NORTH,
X	DB_EAST,
X	DB_SOUTH,
X	DB_WEST
X};
X
X#ifdef ALTARS
Xstatic altar *tmpaltar[256];
X#endif /* ALTARS /**/
Xstatic lad *tmplad[256];
Xstatic digpos *tmpdig[256];
Xstatic char *tmpmap[ROWNO];
Xstatic region *tmpreg[16];
Xstatic door *tmpdoor[256];
Xstatic trap *tmptrap[256];
Xstatic monster *tmpmonst[256];
Xstatic object *tmpobj[256];
Xstatic drawbridge *tmpdb[256];
Xstatic walk *tmpwalk[256];
Xstatic mazepart *tmppart[10];
Xstatic room *tmproom[MAXNROFROOMS];
Xstatic specialmaze maze;
X
Xstatic char olist[MAX_REGISTERS], mlist[MAX_REGISTERS];
Xstatic struct coord plist[MAX_REGISTERS];
Xstatic int n_olist = 0, n_mlist = 0, n_plist = 0;
X
Xunsigned int nreg = 0, ndoor = 0, ntrap = 0, nmons = 0, nobj = 0;
Xunsigned int ndb = 0, nwalk = 0, npart = 0, ndig = 0, nlad = 0;
X#ifdef ALTARS
Xunsigned int naltar = 0;
X#endif /* ALTARS /*/
X
Xunsigned int max_x_map, max_y_map;
X
Xextern int fatal_error;
Xextern char* fname;
X
X%}
X
X%union
X{
X	int	i;
X	char*	map;
X}
X
X
X%token	<i> CHAR INTEGER
X%token	<i> MAZE_ID LEVEL_ID GEOMETRY_ID
X%token	<i> OBJECT_ID MONSTER_ID TRAP_ID DOOR_ID DRAWBRIDGE_ID MAZEWALK_ID
X%token	<i> REGION_ID RANDOM_OBJECTS_ID RANDOM_MONSTERS_ID RANDOM_PLACES_ID
X%token	<i> ALTAR_ID LADDER_ID NON_DIGGABLE_ID ROOM_ID
X%token	<i> DOOR_STATE LIGHT_STATE
X%token	<i> DIRECTION RANDOM_TYPE O_REGISTER M_REGISTER P_REGISTER A_REGISTER
X%token	<i> ALIGNMENT LEFT_OR_RIGHT CENTER TOP_OR_BOT ALTAR_TYPE UP_OR_DOWN
X%token	<i> ',' ':' '(' ')' '[' ']'
X%token	<map> STRING MAP_ID
X%type	<i> h_justif v_justif trap_name room_type door_state light_state
X%type	<i> alignment altar_type a_register
X%type	<map> string maze_def m_name o_name
X%start	file
X
X%%
Xfile		: /* notthing */
X		| levels ;
X
Xlevels		: level
X		| level levels ;
X
Xlevel		: maze_level ;
X
Xmaze_level	: maze_def regions
X		  {
X			  int fout, i;
X
X			  if (fatal_error > 0)
X				  fprintf(stderr,"%s : %d errors detected. No output created!\n", fname, fatal_error);
X			  else {
X#ifdef MACOS
X				  OSErr	result;
X				  
X				  result = Create(CtoPstr($1), 0, CREATOR, AUXIL_TYPE);
X				  (void)PtoCstr($1);
X#endif		
X				  fout = open($1, O_WRONLY | O_CREAT
X#if defined(MSDOS) || defined(MACOS)
X					      | O_BINARY
X#endif /* MSDOS || MACOS */
X					      , 0644);
X				  if (fout < 0) {
X					  yyerror("Can't open output file!!");
X					  exit(1);
X				  }
X				  maze.numpart = npart;
X				  maze.parts = (mazepart**) alloc(sizeof(mazepart*)*npart);
X				  for(i=0;i<npart;i++)
X				      maze.parts[i] = tmppart[i];
X				  write_maze(fout, &maze);
X				  (void) close(fout);
X				  npart = 0;
X			  }
X		  }
X
Xmaze_def	: MAZE_ID ':' string
X		  {
X			  $$ = $3;
X		  }
X
Xregions 	: aregion
X		| aregion regions ;
X
Xaregion 	: map_definition reg_init map_details
X		  {
X			store_part();
X		  }
X
Xmap_definition	: map_geometry MAP_ID
X		  {
X			tmppart[npart] = (mazepart *) alloc(sizeof(mazepart));
X			tmppart[npart]->halign = $<i>1 % 10;
X			tmppart[npart]->valign = $<i>1 / 10;
X			tmppart[npart]->nrobjects = 0;
X			tmppart[npart]->nloc = 0;
X			tmppart[npart]->nrmonst = 0;
X			scan_map($2);
X		  }
X
Xmap_geometry	: GEOMETRY_ID ':' h_justif ',' v_justif
X		  {
X			  $<i>$ = $<i>3 + ( $<i>5 * 10 );
X		  }
X
Xh_justif	: LEFT_OR_RIGHT
X		| CENTER ;
X
Xv_justif	: TOP_OR_BOT
X		| CENTER ;
X
Xreg_init	: /* nothing */
X		| reg_init init_reg ;
X
Xinit_reg	: RANDOM_OBJECTS_ID ':' object_list
X		  {
X			  if (tmppart[npart]->nrobjects)
X			      yyerror("Object registers already initialized!");
X			  else {
X				  tmppart[npart]->robjects = (char *) alloc(n_olist);
X				  memcpy(tmppart[npart]->robjects, olist, n_olist);
X				  tmppart[npart]->nrobjects = n_olist;
X			  }
X		  }
X		| RANDOM_PLACES_ID ':' place_list
X		  {
X			  if (tmppart[npart]->nloc)
X			      yyerror("Location registers already initialized!");
X			  else {
X				  register int i;
X				  tmppart[npart]->rloc_x = (char *) alloc(n_plist);
X				  tmppart[npart]->rloc_y = (char *) alloc(n_plist);
X				  for(i=0;i<n_plist;i++) {
X					  tmppart[npart]->rloc_x[i] = plist[i].x;
X					  tmppart[npart]->rloc_y[i] = plist[i].y;
X				  }
X				  tmppart[npart]->nloc = n_plist;
X			  }
X		  }
X		| RANDOM_MONSTERS_ID ':' monster_list
X		  {
X			  if (tmppart[npart]->nrmonst)
X			      yyerror("Monster registers already initialized!");
X			  else {
X				  tmppart[npart]->rmonst = (char *) alloc(n_mlist);
X				  memcpy(tmppart[npart]->rmonst, mlist, n_mlist);
X				  tmppart[npart]->nrmonst = n_mlist;
X			  }
X		  }
X
Xobject_list	: object
X		  {
X			  if (n_olist < MAX_REGISTERS)
X			      olist[n_olist++] = $<i>1;
X			  else
X			      yyerror("Object list too long!");
X		  }
X		| object ',' object_list
X		  {
X			  if (n_olist < MAX_REGISTERS)
X			      olist[n_olist++] = $<i>1;
X			  else
X			      yyerror("Object list too long!");
X		  }
X
Xmonster_list	: monster
X		  {
X			  if (n_mlist < MAX_REGISTERS)
X			      mlist[n_mlist++] = $<i>1;
X			  else
X			      yyerror("Monster list too long!");
X		  }
X		| monster ',' monster_list
X		  {
X			  if (n_mlist < MAX_REGISTERS)
X			      mlist[n_mlist++] = $<i>1;
X			  else
X			      yyerror("Monster list too long!");
X		  }
X
Xplace_list	: place
X		  {
X			  if (n_plist < MAX_REGISTERS)
X			      plist[n_plist++] = current_coord;
X			  else
X			      yyerror("Location list too long!");
X		  }
X		| place
X		  {
X			  if (n_plist < MAX_REGISTERS)
X			      plist[n_plist++] = current_coord;
X			  else
X			      yyerror("Location list too long!");
X		  } ',' place_list
X
Xmap_details	: /* nothing */
X		| map_details map_detail ;
X
Xmap_detail	: monster_detail
X		| object_detail
X		| door_detail
X		| trap_detail
X		| drawbridge_detail
X		| region_detail
X		| altar_detail
X		| mazewalk_detail
X		| ladder_detail
X		| diggable_detail ;
X
Xmonster_detail	: MONSTER_ID ':' monster_c ',' m_name ',' coordinate
X		  {
X			  int token;
X
X			  tmpmonst[nmons] = (monster *) alloc(sizeof(monster));
X			  tmpmonst[nmons]->x = current_coord.x;
X			  tmpmonst[nmons]->y = current_coord.y;
X			  tmpmonst[nmons]->class = $<i>3;
X			  if (!$5)
X			      tmpmonst[nmons]->id = -1;
X			  else {
X				  token = get_monster_id($5, (char) $<i>3);
X				  if (token == ERR) {
X				      yywarning("Illegal monster name!  Making random monster.");
X				      tmpmonst[nmons]->id = -1;
X				  } else
X				      tmpmonst[nmons]->id = token;
X			  }
X			  nmons++;
X		  }
X
Xobject_detail	: OBJECT_ID ':' object_c ',' o_name ',' coordinate
X		  {
X			  int token;
X
X			  tmpobj[nobj] = (object *) alloc(sizeof(object));
X			  tmpobj[nobj]->x = current_coord.x;
X			  tmpobj[nobj]->y = current_coord.y;
X			  tmpobj[nobj]->class = $<i>3;
X			  if (!$5)
X			      tmpobj[nobj]->id = -1;
X			  else {
X				  token = get_object_id($5, (char) $<i>3);
X				  if (token == ERR) {
X				      yywarning("Illegal object name!  Making random object.");
X				      tmpobj[nobj]->id = -1;
X				  } else
X				      tmpobj[nobj]->id = token;
X			  }
X			  nobj++;
X		  }
X
Xdoor_detail	: DOOR_ID ':' door_state ',' coordinate
X		  {
X			tmpdoor[ndoor] = (door *) alloc(sizeof(door));
X			tmpdoor[ndoor]->x = current_coord.x;
X			tmpdoor[ndoor]->y = current_coord.y;
X			tmpdoor[ndoor]->mask = $<i>3;
X			ndoor++;
X		  }
X
Xtrap_detail	: TRAP_ID ':' trap_name ',' coordinate
X		  {
X			tmptrap[ntrap] = (trap *) alloc(sizeof(trap));
X			tmptrap[ntrap]->x = current_coord.x;
X			tmptrap[ntrap]->y = current_coord.y;
X			tmptrap[ntrap]->type = $<i>3;
X			ntrap++;
X		  }
X
Xdrawbridge_detail: DRAWBRIDGE_ID ':' coordinate ',' DIRECTION ',' door_state
X		   {
X			tmpdb[ndb] = (drawbridge *) alloc(sizeof(drawbridge));
X			tmpdb[ndb]->x = current_coord.x;
X			tmpdb[ndb]->y = current_coord.y;
X			tmpdb[ndb]->dir = db_dirs[$5];
X			if ( $<i>7 == D_ISOPEN )
X			  tmpdb[ndb]->open = 1;
X			else if ( $<i>7 == D_CLOSED )
X			  tmpdb[ndb]->open = 0;
X			else
X			  yyerror("A drawbridge can only be open or closed!");
X			ndb++;
X		   }
X
Xmazewalk_detail : MAZEWALK_ID ':' coordinate ',' DIRECTION
X		  {
X			tmpwalk[nwalk] = (walk *) alloc(sizeof(walk));
X			tmpwalk[nwalk]->x = current_coord.x;
X			tmpwalk[nwalk]->y = current_coord.y;
X			tmpwalk[nwalk]->dir = $5;
X			nwalk++;
X		  }
X
Xladder_detail	: LADDER_ID ':' coordinate ',' UP_OR_DOWN
X		  {
X			tmplad[nlad] = (lad *) alloc(sizeof(lad));
X			tmplad[nlad]->x = current_coord.x;
X			tmplad[nlad]->y = current_coord.y;
X			tmplad[nlad]->up = $<i>5;
X			nlad++;
X		  }
X
Xdiggable_detail : NON_DIGGABLE_ID ':' region
X		  {
X			tmpdig[ndig] = (digpos *) alloc(sizeof(digpos));
X			tmpdig[ndig]->x1 = current_region.x1;
X			tmpdig[ndig]->y1 = current_region.y1;
X			tmpdig[ndig]->x2 = current_region.x2;
X			tmpdig[ndig]->y2 = current_region.y2;
X			ndig++;
X		  }
X
Xregion_detail	: REGION_ID ':' region ',' light_state ',' room_type
X		  {
X			tmpreg[nreg] = (region *) alloc(sizeof(region));
X			tmpreg[nreg]->x1 = current_region.x1;
X			tmpreg[nreg]->y1 = current_region.y1;
X			tmpreg[nreg]->x2 = current_region.x2;
X			tmpreg[nreg]->y2 = current_region.y2;
X			tmpreg[nreg]->rlit = $<i>5;
X			tmpreg[nreg]->rtype = $<i>7;
X			nreg++;
X		  }
X
Xaltar_detail	: ALTAR_ID ':' coordinate ',' alignment ',' altar_type
X		  {
X#ifndef ALTARS
X			yywarning("Altars are not allowed in this version!  Ignoring...");
X#else
X			tmpaltar[naltar] = (altar *) alloc(sizeof(altar));
X			tmpaltar[naltar]->x = current_coord.x;
X			tmpaltar[naltar]->y = current_coord.y;
X			tmpaltar[naltar]->align = $<i>5;
X			tmpaltar[naltar]->shrine = $<i>7;
X			naltar++;
X#endif /* ALTARS */
X		  }
X
Xmonster_c	: monster
X		| RANDOM_TYPE
X		  {
X			  $<i>$ = - MAX_REGISTERS - 1;
X		  }
X		| m_register ;
X
Xobject_c	: object
X		| RANDOM_TYPE
X		  {
X			  $<i>$ = - MAX_REGISTERS - 1;
X		  }
X		| o_register;
X
Xm_name		: string
X		| RANDOM_TYPE
X		  {
X			  $$ = (char *) 0;
X		  }
X
Xo_name		: string
X		| RANDOM_TYPE
X		  {
X			  $$ = (char *) 0;
X		  }
X
Xtrap_name	: string
X		  {
X			int token = get_trap_type($1);
X			if (token == ERR)
X				yyerror("unknown trap type!");
X			$<i>$ = token;
X		  }
X		| RANDOM_TYPE
X
Xroom_type	: string
X		  {
X			int token = get_room_type($1);
X			if (token == ERR) {
X				yywarning("Unknown room type!  Making ordinary room...");
X				$<i>$ = OROOM;
X			} else
X				$<i>$ = token;
X		  }
X		| RANDOM_TYPE
X
Xcoordinate	: coord
X		| p_register
X		| RANDOM_TYPE
X		  {
X			  current_coord.x = current_coord.y = -MAX_REGISTERS-1;
X		  }
X
Xdoor_state	: DOOR_STATE
X		| RANDOM_TYPE
X
Xlight_state	: LIGHT_STATE
X		| RANDOM_TYPE
X
Xalignment	: ALIGNMENT
X		| a_register
X		| RANDOM_TYPE
X		  {
X			  $<i>$ = - MAX_REGISTERS - 1;
X		  }
X
Xaltar_type	: ALTAR_TYPE
X		| RANDOM_TYPE
X
Xp_register	: P_REGISTER '[' INTEGER ']'
X		  {
X			if ( $3 >= MAX_REGISTERS ) {
X				yyerror("Register Index overflow!");
X			} else {
X				current_coord.x = current_coord.y = - $3 - 1;
X			}
X		  }
X
Xo_register	: O_REGISTER '[' INTEGER ']'
X		  {
X			if ( $3 >= MAX_REGISTERS ) {
X				yyerror("Register Index overflow!");
X			} else {
X				$<i>$ = - $3 - 1;
X			}
X		  }
X
Xm_register	: M_REGISTER '[' INTEGER ']'
X		  {
X			if ( $3 >= MAX_REGISTERS ) {
X				yyerror("Register Index overflow!");
X			} else {
X				$<i>$ = - $3 - 1;
X			}
X		  }
X
Xa_register	: A_REGISTER '[' INTEGER ']'
X		  {
X			if ( $3 >= 3 ) {
X				yyerror("Register Index overflow!");
X			} else {
X				$<i>$ = - $3 - 1;
X			}
X		  }
X
Xplace		: coord
X
Xmonster 	: CHAR
X		  {
X			if (check_monster_char((char) $1))
X				$<i>$ = $1 ;
X			else {
X				yyerror("unknown monster class!");
X				$<i>$ = ERR;
X			}
X		  }
X
Xobject		: CHAR
X		  {
X			char c;
X
X			c = $1;
X#ifndef SPELLS
X			if ( c == '+') {
X				c = '?';
X				yywarning("Spellbooks are not allowed in this version! (converted into scroll)");
X			}
X#endif
X			if (check_object_char(c))
X				$<i>$ = c;
X			else {
X				yyerror("Unknown char class!");
X				$<i>$ = ERR;
X			}
X		  }
Xstring		: STRING
X
Xcoord		: '(' INTEGER ',' INTEGER ')'
X		  {
X			if ($2 < 0 || $2 > max_x_map ||
X			    $4 < 0 || $4 > max_y_map)
X			    yyerror("Coordinates out of map range!");
X			current_coord.x = $2;
X			current_coord.y = $4;
X		  }
X
Xregion		: '(' INTEGER ',' INTEGER ',' INTEGER ',' INTEGER ')'
X		  {
X			if ($2 < 0 || $2 > max_x_map ||
X			    $4 < 0 || $4 > max_y_map ||
X			    $6 < 0 || $6 > max_x_map ||
X			    $8 < 0 || $8 > max_y_map)
X			    yyerror("Region out of map range!");
X			current_region.x1 = $2;
X			current_region.y1 = $4;
X			current_region.x2 = $6;
X			current_region.y2 = $8;
X		  }
X
X
X%%
X
X/* 
X * Find the type of a room in the table, knowing its name.
X */
X
Xint
Xget_room_type(s)
Xchar *s;
X{
X	register int i;
X	
X	for(i=0; i < SHOPBASE -1; i++)
X	    if (!strcmp(s, room_types[i].name))
X		return ((int) room_types[i].type);
X	return ERR;
X}
X
X/* 
X * Find the type of a trap in the table, knowing its name.
X */
X
Xint
Xget_trap_type(s)
Xchar *s;
X{
X	register int i;
X	
X	for(i=0; i < TRAPNUM - 1; i++)
X	    if(!strcmp(s,trap_types[i].name))
X		return((int)trap_types[i].type);
X	return ERR;
X}
X
X/* 
X * Find the index of a monster in the table, knowing its name.
X */
X
Xint
Xget_monster_id(s, c)
Xchar *s;
Xchar c;
X{
X	register int i;
X	
X	for(i=0; mons[i].mname[0]; i++)
X	    if(!strncmp(s, mons[i].mname, strlen(mons[i].mname))
X	       && c == mons[i].mlet)
X		return i;
X	return ERR;
X}
X
X/* 
X * Find the index of an object in the table, knowing its name.
X */
X
Xint
Xget_object_id(s, c)
Xchar *s;
Xchar c;
X{
X	register int i;
X	
X	for(i=0; i<=NROFOBJECTS;i++)
X	    if(objects[i].oc_name &&
X	       !strncmp(s, objects[i].oc_name, strlen(objects[i].oc_name))
X	       && c == objects[i].oc_olet)
X		return i;
X	return ERR;
X}
X
X/* 
X * Is the character 'c' a valid monster class ?
X */
X
Xboolean
Xcheck_monster_char(c)
Xchar c;
X{
X	register int i;
X	
X	for(i=0; mons[i].mname[0]; i++)
X	    if( c ==  mons[i].mlet)
X		return 1;
X	return(0);
X}
X
X/* 
X * Is the character 'c' a valid object class ?
X */
X
Xboolean
Xcheck_object_char(c)
Xchar c;
X{
X	register int i;
X	
X	for(i=0; i<=NROFOBJECTS;i++)
X	    if( c == objects[i].oc_olet)
X		return 1;
X	return 0;
X}
X
X/* 
X * Yep! LEX gives us the map in a raw mode.
X * Just analyze it here.
X */
X
Xvoid scan_map(map)
Xchar *map;
X{
X	register int i, len;
X	register char *s1, *s2;
X	int max_len = 0;
X	int max_hig = 0;
X	
X	/* First : find the max width of the map */
X
X	s1 = map;
X	while (s1 && *s1) {
X		s2 = index(s1, '\n');
X		if (s2) {
X			if (s2-s1 > max_len)
X			    max_len = s2-s1;
X			s1 = s2 + 1;
X		} else {
X			if (strlen(s1) > max_len)
X			    max_len = strlen(s1);
X			s1 = (char *) 0;
X		}
X	}
X
X	/* Then parse it now */
X
X	while (map && *map) {
X		tmpmap[max_hig] = (char *) alloc(max_len);
X		s1 = index(map, '\n');
X		if (s1) {
X			len = s1 - map;
X			s1++;
X		} else {
X			len = strlen(map);
X			s1 = map + len;
X		}
X		for(i=0; i<len; i++)
X		    switch(map[i]) {
X			  case '-' : tmpmap[max_hig][i] = HWALL; break;
X			  case '|' : tmpmap[max_hig][i] = VWALL; break;
X			  case '+' : tmpmap[max_hig][i] = DOOR; break;
X			  case 'S' : tmpmap[max_hig][i] = SDOOR; break;
X			  case '{' : 
X#ifdef FOUNTAINS
X			      tmpmap[max_hig][i] = FOUNTAIN;
X#else
X			      tmpmap[max_hig][i] = ROOM;
X			      yywarning("Fountains are not allowed in this version!  Ignoring...");
X#endif
X			      break;
X			  case '\\' : 
X#ifdef THRONES
X			      tmpmap[max_hig][i] = THRONE;
X#else
X			      tmpmap[max_hig][i] = ROOM;
X			      yywarning("Thrones are not allowed in this version!  Ignoring...");
X#endif
X			      break;
X			  case 'K' : 
X#ifdef SINKS
X			      tmpmap[max_hig][i] = SINK;
X#else
X			      tmpmap[max_hig][i] = ROOM;
X			      yywarning("Sinks are not allowed in this version!  Ignoring...");
X#endif
X			      break;
X			  case '}' : tmpmap[max_hig][i] = MOAT; break;
X			  case '#' : tmpmap[max_hig][i] = CORR; break;
X			  default  : tmpmap[max_hig][i] = ROOM; break;
X		    }
X		while(i < max_len)
X		    tmpmap[max_hig][i++] = ROOM;
X		map = s1;
X		max_hig++;
X	}
X
X	/* Memorize boundaries */
X
X	max_x_map = max_len - 1;
X	max_y_map = max_hig - 1;
X
X	/* Store the map into the mazepart structure */
X
X	tmppart[npart]->xsize = max_len;
X	tmppart[npart]->ysize = max_hig;
X	tmppart[npart]->map = (char **) alloc(max_hig*sizeof(char *));
X	for(i = 0; i< max_hig; i++)
X	    tmppart[npart]->map[i] = tmpmap[i];
X}
X
X/* 
X * Here we want to store the maze part we just got.
X */
X
Xvoid
Xstore_part()
X{
X	register int i;
X
X	/* Ok, We got the whole part, now we store it. */
X	
X	/* The Regions */
X
X	if(tmppart[npart]->nreg = nreg) {
X		tmppart[npart]->regions = (region**)alloc(sizeof(region*) * nreg);
X		for(i=0;i<nreg;i++)
X		    tmppart[npart]->regions[i] = tmpreg[i];
X	}
X	nreg = 0;
X
X	/* the doors */
X
X	if(tmppart[npart]->ndoor = ndoor) {
X		tmppart[npart]->doors = (door **)alloc(sizeof(door *) * ndoor);
X		for(i=0;i<ndoor;i++)
X		    tmppart[npart]->doors[i] = tmpdoor[i];
X	}
X	ndoor = 0;
X
X	/* the traps */
X
X	if(tmppart[npart]->ntraps = ntrap) {
X		tmppart[npart]->traps = (trap **)alloc(sizeof(trap*) * ntrap);
X		for(i=0;i<ntrap;i++)
X		    tmppart[npart]->traps[i] = tmptrap[i];
X	}
X	ntrap = 0;
X
X	/* the monsters */
X
X	if(tmppart[npart]->nmonster = nmons) {
X		tmppart[npart]->monsters = (monster**)alloc(sizeof(monster*)*nmons);
X		for(i=0;i<nmons;i++)
X		    tmppart[npart]->monsters[i] = tmpmonst[i];
X	}
X	nmons = 0;
X
X	/* the objects */
X
X	if(tmppart[npart]->nobjects = nobj) {
X		tmppart[npart]->objects = (object**)alloc(sizeof(object*)*nobj);
X		for(i=0;i<nobj;i++)
X		    tmppart[npart]->objects[i] = tmpobj[i];
X	}
X	nobj = 0;
X
X	/* the drawbridges */
X
X	if(tmppart[npart]->ndrawbridge = ndb) {
X		tmppart[npart]->drawbridges = (drawbridge**)alloc(sizeof(drawbridge*)*ndb);
X		for(i=0;i<ndb;i++)
X		    tmppart[npart]->drawbridges[i] = tmpdb[i];
X	}
X	ndb = 0;
X
X	/* The walkmaze directives */
X
X	if(tmppart[npart]->nwalk = nwalk) {
X		tmppart[npart]->walks = (walk**)alloc(sizeof(walk*)*nwalk);
X		for(i=0;i<nwalk;i++)
X		    tmppart[npart]->walks[i] = tmpwalk[i];
X	}
X	nwalk = 0;
X
X	/* The non_diggable directives */
X
X	if(tmppart[npart]->ndig = ndig) {
X		tmppart[npart]->digs = (digpos **) alloc(sizeof(digpos*) * ndig);
X		for(i=0;i<ndig;i++)
X		    tmppart[npart]->digs[i] = tmpdig[i];
X	}
X	ndig = 0;
X
X	/* The ladders */
X
X	if(tmppart[npart]->nlad = nlad) {
X		tmppart[npart]->lads = (lad **) alloc(sizeof(lad*) * nlad);
X		for(i=0;i<nlad;i++)
X		    tmppart[npart]->lads[i] = tmplad[i];
X	}
X	nlad = 0;
X#ifdef ALTARS
X	/* The altars */
X
X	if(tmppart[npart]->naltar = naltar) {
X		tmppart[npart]->altars = (altar**)alloc(sizeof(altar*) * naltar);
X		for(i=0;i<naltar;i++)
X		    tmppart[npart]->altars[i] = tmpaltar[i];
X	}
X	naltar = 0;
X#endif /* ALTARS /**/
X	npart++;
X	n_plist = n_mlist = n_olist = 0;
X}
X
X/* 
X * Here we write the structure of the maze in the specified file (fd).
X * Also, we have to free the memory allocated via alloc()
X */
X
Xvoid
Xwrite_maze(fd, maze)
Xint fd;
Xspecialmaze *maze;
X{
X	char c;
X	short i,j;
X	mazepart *pt;
X
X	c = 2;
X	(void) write(fd, &c, 1);	/* Header for special mazes */
X	(void) write(fd, &(maze->numpart), 1);	/* Number of parts */
X	for(i=0;i<maze->numpart;i++) {
X	    pt = maze->parts[i];
X
X	    /* First, write the map */
X
X	    (void) write(fd, &(pt->halign), 1);
X	    (void) write(fd, &(pt->valign), 1);
X	    (void) write(fd, &(pt->xsize), 1);
X	    (void) write(fd, &(pt->ysize), 1);
X	    for(j=0;j<pt->ysize;j++) {
X		    (void) write(fd, pt->map[j], pt->xsize);
X		    free(pt->map[j]);
X	    }
X	    free(pt->map);
X
X	    /* The random registers */
X	    (void) write(fd, &(pt->nrobjects), 1);
X	    if(pt->nrobjects) {
X		    (void) write(fd, pt->robjects, pt->nrobjects);
X		    free(pt->robjects);
X	    }
X	    (void) write(fd, &(pt->nloc), 1);
X	    if(pt->nloc) {
X		(void) write(fd,pt->rloc_x, pt->nloc);
X		(void) write(fd,pt->rloc_y, pt->nloc);
X		free(pt->rloc_x);
X		free(pt->rloc_y);
X	    }
X	    (void) write(fd,&(pt->nrmonst), 1);
X	    if(pt->nrmonst) {
X		    (void) write(fd, pt->rmonst, pt->nrmonst);
X		    free(pt->rmonst);
X	    }
X
X	    /* subrooms */
X	    (void) write(fd, &(pt->nreg), 1);
X	    for(j=0;j<pt->nreg;j++) {
X		    (void) write(fd,(genericptr_t) pt->regions[j], sizeof(region));
X		    free(pt->regions[j]);
X	    }
X	    if(pt->nreg > 0)
X		free(pt->regions);
X
X	    /* the doors */
X	    (void) write(fd,&(pt->ndoor),1);
X	    for(j=0;j<pt->ndoor;j++) {
X		    (void) write(fd,(genericptr_t) pt->doors[j], sizeof(door));
X		    free(pt->doors[j]);
X	    }
X	    if (pt->ndoor > 0)
X		free(pt->doors);
X
X	    /* The traps */
X	    (void) write(fd,&(pt->ntraps), 1);
X	    for(j=0;j<pt->ntraps;j++) {
X		    (void) write(fd,(genericptr_t) pt->traps[j], sizeof(trap));
X		    free(pt->traps[j]);
X	    }
X	    if (pt->ntraps)
X		free(pt->traps);
X
X	    /* The monsters */
X	    (void) write(fd, &(pt->nmonster), 1);
X	    for(j=0;j<pt->nmonster;j++) {
X		    (void) write(fd,(genericptr_t) pt->monsters[j], sizeof(monster));
X		    free(pt->monsters[j]);
X	    }
X	    if (pt->nmonster > 0)
X		free(pt->monsters);
X
X	    /* The objects */
X	    (void) write(fd, &(pt->nobjects), 1);
X	    for(j=0;j<pt->nobjects;j++) {
X		    (void) write(fd,(genericptr_t) pt->objects[j], sizeof(object));
X		    free(pt->objects[j]);
X	    }
X	    if(pt->nobjects > 0)
X		free(pt->objects);
X
X	    /* The drawbridges */
X	    (void) write(fd, &(pt->ndrawbridge),1);
X	    for(j=0;j<pt->ndrawbridge;j++) {
X		    (void) write(fd,(genericptr_t) pt->drawbridges[j], sizeof(drawbridge));
X		    free(pt->drawbridges[j]);
X	    }
X	    if(pt->ndrawbridge > 0)
X		free(pt->drawbridges);
X
X	    /* The mazewalk directives */
X	    (void) write(fd, &(pt->nwalk), 1);
X	    for(j=0; j<pt->nwalk; j++) {
X		    (void) write(fd,(genericptr_t) pt->walks[j], sizeof(walk));
X		    free(pt->walks[j]);
X	    }
X	    if (pt->nwalk > 0)
X		free(pt->walks);
X
X	    /* The non_diggable directives */
X	    (void) write(fd, &(pt->ndig), 1);
X	    for(j=0;j<pt->ndig;j++) {
X		    (void) write(fd,(genericptr_t) pt->digs[j], sizeof(digpos));
X		    free(pt->digs[j]);
X	    }
X	    if (pt->ndig > 0)
X		free(pt->digs);
X
X	    /* The ladders */
X	    (void) write(fd, &(pt->nlad), 1);
X	    for(j=0;j<pt->nlad;j++) {
X		    (void) write(fd,(genericptr_t) pt->lads[j], sizeof(lad));
X		    free(pt->lads[j]);
X	    }
X	    if (pt->nlad > 0)
X		free(pt->lads);
X#ifdef ALTARS
X	    /* The altars */
X	    (void) write(fd, &(pt->naltar), 1);
X	    for(j=0;j<pt->naltar;j++) {
X		    (void) write(fd,(genericptr_t) pt->altars[j], sizeof(altar));
X		    free(pt->altars[j]);
X	    }
X	    if (pt->naltar > 0)
X		free(pt->altars);
X#endif /* ALTARS /**/
X	    free(pt);
X	}
X}
END_OF_FILE
if test 24370 -ne `wc -c <'src/lev_comp.y'`; then
    echo shar: \"'src/lev_comp.y'\" unpacked with wrong size!
fi
# end of 'src/lev_comp.y'
fi
if test -f 'src/pri.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/pri.c'\"
else
echo shar: Extracting \"'src/pri.c'\" \(29052 characters\)
sed "s/^X//" >'src/pri.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)pri.c	3.0	89/11/15
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#define MONATTK_H	/* comment line for pre-compiled headers */
X/* block some unused #defines to avoid overloading some cpp's */
X#include "hack.h"
X#if defined(ALTARS) && defined(THEOLOGY)
X#include "epri.h"
X#endif
X#include "termcap.h"
X
X#ifdef OVL0
Xstatic void FDECL(fillbot, (int,char *,char *));
Xstatic void NDECL(bot1);
Xstatic void NDECL(bot2);
X#endif /* OVL0 */
X
XSTATIC_DCL void FDECL(hilite, (int,int,UCHAR_P, UCHAR_P));
XSTATIC_DCL void FDECL(cornbot, (int));
X#ifdef TEXTCOLOR
XSTATIC_DCL uchar FDECL(mimic_color, (struct monst *));
X#endif
X
X#ifdef OVL0
X# ifndef ASCIIGRAPH
X# define g_putch  (void) putchar
X# endif /* ASCIIGRAPH */
X
X# ifndef g_putch
Xstatic void FDECL(g_putch, (UCHAR_P));
Xstatic boolean GFlag = FALSE; /* graphic flag */
X# endif
X#endif /* OVL0 */
X
X/* 100 suffices for bot(); must be larger than COLNO */
X#define MAXCO 100
XSTATIC_VAR char NEARDATA oldbot1[MAXCO], NEARDATA newbot1[MAXCO];
XSTATIC_VAR char NEARDATA oldbot2[MAXCO], NEARDATA newbot2[MAXCO];
X#ifdef OVL2
Xstatic const char NEARDATA *dispst = "*0#@#0#*0#@#0#*0#@#0#*0#@#0#*0#@#0#*";
X#endif /* OVL2 */
X#ifndef OVLB
XSTATIC_DCL int mrank_sz;
X#else /* OVLB */
XSTATIC_OVL int NEARDATA mrank_sz = 0;  /* loaded by max_rank_sz (called in u_init) */
X#endif /* OVLB */
X
X#ifdef CLIPPING
X#define curs(x, y) (void) win_curs((x), (y)-2)
X#endif
X
X#ifdef OVL0
X
Xchar *
Xeos(s)
Xregister char *s;
X{
X	while(*s) s++;
X	return(s);
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xswallowed(first)
Xregister int first;
X{
X	if(first) cls();
X	else {
X		curs(u.ustuck->mdx-1, u.ustuck->mdy+1);
X#ifdef MACOS
X		puts("   ");
X#else
X		(void) fputs("   ", stdout);
X#endif
X		curx = u.ustuck->mdx+2;
X		curs(u.ustuck->mdx-1, u.ustuck->mdy+2);
X#ifdef MACOS
X		puts("   ");
X#else
X		(void) fputs("   ", stdout);
X#endif
X		curx = u.ustuck->mdx+2;
X		curs(u.ustuck->mdx-1, u.ustuck->mdy+3);
X#ifdef MACOS
X		puts("   ");
X#else
X		(void) fputs("   ", stdout);
X#endif
X		curx = u.ustuck->mdx+2;
X	}
X	curs(u.ux-1, u.uy+1);
X#ifdef MACOS
X	puts("/-\\");
X#else
X	(void) fputs("/-\\", stdout);
X#endif
X	curx = u.ux+2;
X	curs(u.ux-1, u.uy+2);
X	(void) putchar('|');
X	hilite(u.ux, u.uy, u.usym, AT_MON);
X	(void) putchar('|');
X	curx = u.ux+2;
X	curs(u.ux-1, u.uy+3);
X#ifdef MACOS
X	puts("\\-/");
X#else
X	(void) fputs("\\-/", stdout);
X#endif
X	curx = u.ux+2;
X	u.udispl = 1;
X	u.udisx = u.ux;
X	u.udisy = u.uy;
X}
X#ifdef CLIPPING
X#undef curs
X#endif
X
Xvoid
Xsetclipped()
X{
X#ifndef CLIPPING
X	error("NetHack needs a screen of size at least %d by %d.\n",
X		ROWNO+3, COLNO);
X#else
X	clipping = TRUE;
X	clipx = clipy = 0;
X	clipxmax = CO;
X	clipymax = LI - 3;
X#endif
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
X#ifdef CLIPPING
Xvoid
Xcliparound(x, y)
Xint x, y;
X{
X	int oldx = clipx, oldy = clipy;
X
X	if (!clipping) return;
X	if (x < clipx + 5) {
X		clipx = max(0, x - 20);
X		clipxmax = clipx + CO;
X	}
X	else if (x > clipxmax - 5) {
X		clipxmax = min(COLNO, clipxmax + 20);
X		clipx = clipxmax - CO;
X	}
X	if (y < clipy + 2) {
X		clipy = max(0, y - 10);
X		clipymax = clipy + (LI - 3);
X	}
X	else if (y > clipymax - 2) {
X		clipymax = min(ROWNO, clipymax + 10);
X		clipy = clipxmax - (LI - 3);
X	}
X	if (clipx != oldx || clipy != oldy) {
X		if (u.udispl) {
X			u.udispl = 0;
X			levl[u.udisx][u.udisy].scrsym = news0(u.udisx, u.udisy);
X		}
X		(void) doredraw();
X	}
X}
X#endif /* CLIPPING */
X
X/*
X *  Allow for a different implementation than this...
X */
X
X#ifndef g_putch
X
Xstatic void
Xg_putch(ch)
Xuchar ch;
X{
X	if (flags.IBMgraphics)
X		/* IBM-compatible displays don't need other stuff */
X		(void) putchar(ch);
X	else if (ch & 0x80) {
X		if (!GFlag) {
X			graph_on();
X			GFlag = TRUE;
X		}
X		(void) putchar(ch ^ 0x80); /* Strip 8th bit */
X	} else {
X		if (GFlag) {
X			graph_off();
X			GFlag = FALSE;
X		}
X		(void) putchar(ch);
X	}
X}
X
X#endif
X
Xboolean
Xshowmon(mon)
Xregister struct monst *mon;
X{
X	register boolean show = (Blind && Telepat) || canseemon(mon);
X
X	if (!show && (HTelepat & WORN_HELMET))
X		show = (dist(mon->mx, mon->my) <= (BOLT_LIM * BOLT_LIM));
X	return(show);
X}
X
Xvoid
Xat(x,y,ch,typ)
Xregister xchar x,y;
Xuchar ch,typ;
X{
X#ifndef LINT
X	/* if xchar is unsigned, lint will complain about  if(x < 0)  */
X	if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
X		impossible("At gets 0%o at %d %d.", ch, x, y);
X		return;
X	}
X#endif
X	if(!ch) {
X		impossible("At gets null at %d %d.", x, y);
X		return;
X	}
X
X	if (typ == AT_APP
X#if !defined(MSDOS) && !defined(MACOS)
X	    && flags.standout
X#endif
X	   )
X		/* don't hilite if this isn't a monster or object.
X		 *
X		 * not complete; a scroll dropped by some monster
X		 * on an unseen doorway which is later magic mapped
X		 * will still hilite the doorway symbol.  -3.
X		 */
X		if (!vism_at(x,y) &&
X		    (!OBJ_AT(x, y) && !levl[x][y].gmask || is_pool(x,y)))
X		    typ = AT_MAP;
X
X#ifdef CLIPPING
X	if (win_curs(x, y)) {
X#else
X	curs(x,y+2);
X#endif
X	hilite(x, y, ch, typ);
X	curx++;
X#ifdef CLIPPING
X	}
X#endif
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xprme(){
X	if(!Invisible
X#ifdef POLYSELF
X			&& !u.uundetected
X#endif
X					) {
X		levl[u.ux][u.uy].seen = 0; /* force atl */
X		atl(u.ux,u.uy,(char)u.usym);
X	}
X}
X
X#endif /* OVLB */
X#ifdef OVL2
X
Xvoid
Xshieldeff(x, y)		/* produce a magical shield effect at x,y */
X	register xchar x, y;
X{
X	register const char *ch;
X	register struct monst *mtmp = 0;
X
X	nscr();
X
X	if((x == u.ux) && (y == u.uy)) 
X		curs_on_u();
X	else {
X	    if(!(mtmp = m_at(x, y))) {
X
X		impossible("shield effect at %d,%d", x, y);
X		return;
X	    }
X	    if(!showmon(mtmp)) return;
X	}
X
X	for(ch = dispst; *ch; ch++)  {
X		at(x, y, (uchar) *ch, AT_ZAP);
X		(void) fflush(stdout);
X		delay_output();
X		delay_output();
X	}
X
X	nomul(0);
X	if(!mtmp) {
X		if(Invisible) {
X			prl(x, y);
X			at(x, y, levl[x][y].scrsym, AT_APP);
X		} else prme();
X	} else {
X		mtmp->mdispl = 0;	/* make sure it gets redrawn */
X		prl(x, y);
X		if(mtmp->minvis)
X			at(x, y, levl[x][y].scrsym, AT_APP);
X		else	at(x, y, (uchar) mtmp->data->mlet, AT_MON);
X	}
X
X	return;
X}
X
X#endif /* OVL2 */
X#ifdef OVLB
X
Xint
Xdoredraw()
X{
X	docrt();
X	return 0;
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xvoid
Xdocrt()
X{
X	register int x,y;
X	register struct rm *room;
X	register struct monst *mtmp;
X#ifdef MACOS
X	term_info	*t;
X	extern WindowPtr HackWindow;
X#endif
X
X	if(u.uswallow) {
X		swallowed(1);
X		return;
X	}
X	cls();
X
X/* Some ridiculous code to get display of @ and monsters (almost) right */
X	if(!Invisible
X#ifdef POLYSELF
X			&& !u.uundetected
X#endif
X					) {
X		u.udisx = u.ux;
X		u.udisy = u.uy;
X		levl[u.udisx][u.udisy].scrsym = u.usym;
X		levl[u.udisx][u.udisy].seen = 1;
X		u.udispl = 1;
X	} else	u.udispl = 0;
X
X	seemons();	/* reset old positions */
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X		mtmp->mdispl = 0;
X	seemons();	/* force new positions to be shown */
X
X#if ((defined(DGK) && !defined(TEXTCOLOR)) || defined(MACOS)) && !defined(CLIPPING)
X# ifdef MACOS
X	t = (term_info *)GetWRefCon(HackWindow);
X	if (!t->inColor)
X# endif
X	/* Otherwise, line buffer the output to do the redraw in
X	 * about 2/3 of the time.
X	 */
X		for(y = 0; y < ROWNO; y++) {
X			char buf[COLNO+1];
X			int start, end;
X# if defined(LSC) || defined(AZTEC) || defined(AZTEC_C)
X			setmem(buf, COLNO, ' ');
X# else
X			memset(buf, ' ', COLNO);
X# endif
X			for(x = 0, start = -1, end = -1; x < COLNO; x++)
X				if((room = &levl[x][y])->new) {
X					room->new = 0;
X					buf[x] = room->scrsym;
X					if (start < 0)
X						start = x;
X					end = x;
X				} else if(room->seen) {
X					buf[x] = room->scrsym;
X					if (start < 0)
X						start = x;
X					end = x;
X				}
X			if (end >= 0) {
X				buf[end + 1] = '\0';
X				curs(start, y + 2);
X# ifdef MACOS
X				puts(buf + start);
X# else
X				(void) fputs(buf + start, stdout);
X# endif
X				curx = end + 1;
X			}
X		}
X# ifdef MACOS
X	else {
X		for(y = 0; y < ROWNO; y++)
X		for(x = 0; x < COLNO; x++)
X			if((room = &levl[x][y])->new) {
X				room->new = 0;
X				at(x,y,room->scrsym,AT_APP);
X			} else if(room->seen)
X				at(x,y,room->scrsym,AT_APP);
X	}
X# endif
X#else
X	for(y = 0; y < ROWNO; y++)
X		for(x = 0; x < COLNO; x++)
X			if((room = &levl[x][y])->new) {
X				room->new = 0;
X				at(x,y,room->scrsym,AT_APP);
X			} else if(room->seen)
X				at(x,y,room->scrsym,AT_APP);
X#endif /* DGK && !TEXTCOLOR && !CLIPPING */
X#ifndef g_putch
X	if (GFlag) {
X		graph_off();
X		GFlag = FALSE;
X	}
X#endif
X	scrlx = COLNO;
X	scrly = ROWNO;
X	scrhx = scrhy = 0;
X	cornbot(0);
X	bot();
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
XSTATIC_OVL void
Xcornbot(lth)
Xregister int lth;
X{
X	oldbot1[lth] = 0;
X	oldbot2[lth] = 0;
X	flags.botl = 1;
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xvoid
Xdocorner(xmin, ymax)
Xregister int xmin, ymax;
X{
X	register int x, y;
X	register struct rm *room;
X	register struct monst *mtmp;
X
X	if(u.uswallow) {	/* Can be done more efficiently */
X		swallowed(1);
X		return;
X	}
X
X#ifdef CLIPPING
X	xmin += clipx; ymax += clipy;
X#endif
X	seemons();	/* reset old positions */
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X	    if(mtmp->mx >= xmin && mtmp->my < ymax)
X		mtmp->mdispl = 0;
X	seemons();	/* force new positions to be shown */
X
X#ifdef CLIPPING
X	for(y = clipy; y < ymax; y++) {
X		if(clipping && y > clipymax && CD) break;
X		curs(xmin - clipx, (y - clipy)+2);
X#else
X	for(y = 0; y < ymax; y++) {
X		if(y > ROWNO+1 && CD) break;
X		curs(xmin,y+2);
X#endif
X		cl_end();
X		if(y < ROWNO) {
X		    for(x = xmin; x < COLNO; x++) {
X			if((room = &levl[x][y])->new) {
X				room->new = 0;
X				at(x,y,room->scrsym,AT_APP);
X			} else
X				if(room->seen)
X					at(x,y,room->scrsym,AT_APP);
X		    }
X		}
X	}
X#ifndef g_putch
X	if (GFlag) {
X		graph_off();
X		GFlag = FALSE;
X	}
X#endif
X	/* Note:          y values: 0 to ymax-1
X	 * screen positions from y: 2 to ymax+1
X	 *            whole screen: 1 to ROWNO+3
X	 *                top line: 1
X	 *         dungeon display: 2 to ROWNO+1
X	 *       first bottom line: ROWNO+2
X	 *      second bottom line: ROWNO+3
X	 *         lines on screen: ROWNO+3
X	 */
X	if(ymax > ROWNO) {
X		cornbot(xmin-1);
X		if(ymax > ROWNO+2 && CD) {	/* clear portion of long */
X			curs(1,ROWNO+4);	/* screen below status lines */
X			cl_eos();
X		}
X	}
X}
X
X#endif /* OVL0 */
X#ifdef OVL1
X
Xvoid
Xseeglds()
X{
X	register struct gold *gold, *gold2;
X
X	for(gold = fgold; gold; gold = gold2) {
X	    gold2 = gold->ngold;
X	    if(Hallucination && cansee(gold->gx,gold->gy))
X		if(!(gold->gx == u.ux && gold->gy == u.uy) || Invisible)
X		    atl(gold->gx,gold->gy,rndobjsym());
X	}
X}
X
X/* Trolls now regenerate thanks to KAA */
X
Xvoid
Xseeobjs()
X{
X	register struct obj *obj, *obj2;
X
X	for(obj = fobj; obj; obj = obj2) {
X	    obj2 = obj->nobj;
X
X	    if(Hallucination && cansee(obj->ox,obj->oy))
X		if(!(obj->ox == u.ux && obj->oy == u.uy) || Invisible)
X		    atl(obj->ox,obj->oy,rndobjsym());
X
X	    if(obj->olet == FOOD_SYM && obj->otyp == CORPSE) {
X
X		if(mons[obj->corpsenm].mlet == S_TROLL &&
X		    obj->age + 20 < monstermoves) {
X			boolean visible = cansee(obj->ox,obj->oy);
X			struct monst *mtmp = revive(obj, FALSE);
X
X			if (mtmp && visible)
X				pline("%s rises from the dead!",
X					(mtmp->mhp==mtmp->mhpmax) ? Monnam(mtmp)
X					: Amonnam(mtmp, "bite-covered"));
X		} else if (obj->corpsenm != PM_LIZARD &&
X						obj->age + 250 < monstermoves)
X			delobj(obj);
X	    }
X	}
X
X	for(obj = invent; obj; obj = obj2) {
X	    obj2 = obj->nobj;
X	    if(obj->otyp == CORPSE) {
X		if(mons[obj->corpsenm].mlet == S_TROLL
X			    && obj->age + 20 < monstermoves) {
X		    boolean wielded = (obj==uwep);
X		    struct monst *mtmp = revive(obj, TRUE);
X
X		    if (mtmp && wielded)
X			pline("The %s%s %s writhes out of your grasp!",
X				(mtmp->mhp < mtmp->mhpmax) ? "bite-covered ":"",
X				mtmp->data->mname, xname(obj));
X		    else if (mtmp)
X			You("feel squirming in your backpack!");
X		} else if (obj->corpsenm != PM_LIZARD &&
X						obj->age + 250 < monstermoves)
X		    useup(obj);
X	    }
X	}
X}
X
X#endif /* OVL1 */
X#ifdef OVL0
X
Xvoid
Xseemons()
X{
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X	    if(mtmp->data->mlet == S_EEL)
X		mtmp->minvis = (u.ustuck != mtmp && is_pool(mtmp->mx,mtmp->my));
X	    pmon(mtmp);
X#ifdef WORM
X	    if(mtmp->wormno) wormsee(mtmp->wormno);
X#endif
X	}
X}
X
Xvoid
Xpmon(mon)
Xregister struct monst *mon;
X{
X	register int show = showmon(mon);
X
X	if(mon->mdispl)
X	    if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
X		unpmon(mon);
X
X/* If you're hallucinating, the monster must be redrawn even if it has
X * already been printed.
X */
X	if(show && (!mon->mdispl || Hallucination)) {
X	    if (Hallucination)
X	    atl(mon->mx,mon->my,
X		(char) ((!mon->mimic || Protection_from_shape_changers) ?
X		rndmonsym() : (mon->m_ap_type == M_AP_FURNITURE) ?
X		showsyms[mon->mappearance] : rndobjsym()));
X	    else
X
X		atl(mon->mx,mon->my,
X		    (!mon->m_ap_type ||
X		     Protection_from_shape_changers) ?
X		     mon->data->mlet : (char) mimic_appearance(mon));
X		mon->mdispl = 1;
X		mon->mdx = mon->mx;
X		mon->mdy = mon->my;
X	}
X#ifndef g_putch
X	if (GFlag) {
X		graph_off();
X		GFlag = FALSE;
X	}
X#endif
X}
X
X#endif /* OVL0 */
X#ifdef OVL1
X
Xvoid
Xunpmon(mon)
Xregister struct monst *mon;
X{
X	if(mon->mdispl) {
X		newsym(mon->mdx, mon->mdy);
X		mon->mdispl = 0;
X	}
X}
X
X#endif /* OVL1 */
X#ifdef OVL0
X
Xvoid
Xnscr() {
X	register int x, y;
X	register struct rm *room;
X
X	if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
X	pru();
X	for(y = scrly; y <= scrhy; y++)
X		for(x = scrlx; x <= scrhx; x++)
X			if((room = &levl[x][y])->new) {
X				room->new = 0;
X				at(x,y,room->scrsym,AT_APP);
X			}
X#ifndef g_putch
X	if (GFlag) {
X		graph_off();
X		GFlag = FALSE;
X	}
X#endif
X	scrhx = scrhy = 0;
X	scrlx = COLNO;
X	scrly = ROWNO;
X}
X
X#endif /* OVL0 */
X#ifdef OVL1
X
X/* Make sure that there are 18 entries in the rank arrays. */
X/* 0 and even entries are male ranks, odd entries are female. */
X
Xstatic const char NEARDATA *mage_ranks[] = {
X	"Evoker",
X	"Evoker",
X	"Conjurer",
X	"Conjurer",
X	"Thaumaturge",
X	"Thaumaturge",
X	"Magician",
X	"Magician",
X	"Enchanter",
X	"Enchanter",
X	"Sorcerer",
X	"Sorceress",
X	"Necromancer",
X	"Necromancer",
X	"Wizard",
X	"Wizard",
X	"Mage",
X	"Mage"
X};
X
Xstatic const char NEARDATA *priest_ranks[] = {
X	"Aspirant",
X	"Aspirant",
X	"Acolyte",
X	"Acolyte",
X	"Adept",
X	"Adept",
X	"Priest",
X	"Priestess",
X	"Curate",
X	"Curate",
X	"Canon",
X	"Canoness",
X	"Lama",
X	"Lama",
X	"Patriarch",
X	"Matriarch",
X	"High Priest",
X	"High Priestess"
X};
X
Xstatic const char NEARDATA *thief_ranks[] = {
X	"Footpad",
X	"Footpad",
X	"Cutpurse",
X	"Cutpurse",
X	"Rogue",
X	"Rogue",
X	"Pilferer",
X	"Pilferer",
X	"Robber",
X	"Robber",
X	"Burglar",
X	"Burglar",
X	"Filcher",
X	"Filcher",
X	"Magsman",
X	"Magswoman",
X	"Thief",
X	"Thief"
X};
X
Xstatic const char NEARDATA *fighter_ranks[] = {
X	"Stripling",
X	"Stripling",
X	"Skirmisher",
X	"Skirmisher",
X	"Fighter",
X	"Fighter",
X	"Man-at-arms",
X	"Woman-at-arms",
X	"Warrior",
X	"Warrior",
X	"Swashbuckler",
X	"Swashbuckler",
X	"Hero",
X	"Heroine",
X	"Champion",
X	"Champion",
X	"Lord",
X	"Lady"
X};
X
Xstatic const char NEARDATA *tourist_ranks[] = {
X	"Rambler",
X	"Rambler",
X	"Sightseer",
X	"Sightseer",
X	"Excursionist",
X	"Excursionist",
X	"Peregrinator",
X	"Peregrinator",
X	"Traveler",
X	"Traveler",
X	"Journeyer",
X	"Journeyer",
X	"Voyager",
X	"Voyager",
X	"Explorer",
X	"Explorer",
X	"Adventurer",
X	"Adventurer"
X};
X
Xstatic const char NEARDATA *nomad_ranks[] = {
X	"Troglodyte",
X	"Troglodyte",
X	"Aborigine",
X	"Aborigine",
X	"Wanderer",
X	"Wanderer",
X	"Vagrant",
X	"Vagrant",
X	"Wayfarer",
X	"Wayfarer",
X	"Roamer",
X	"Roamer",
X	"Nomad",
X	"Nomad",
X	"Rover",
X	"Rover",
X	"Pioneer",
X	"Pioneer"
X};
X
Xstatic const char NEARDATA *knight_ranks[] = {
X	"Gallant",
X	"Gallant",
X	"Esquire",
X	"Esquire",
X	"Bachelor",
X	"Bachelor",
X	"Sergeant",
X	"Sergeant",
X	"Knight",
X	"Knight",
X	"Banneret",
X	"Banneret",
X	"Chevalier",
X	"Chevalier",
X	"Seignieur",
X	"Seignieur",
X	"Paladin",
X	"Paladin"
X};
X
Xstatic const char NEARDATA *archeo_ranks[] = {
X	"Digger",
X	"Digger",
X	"Field Worker",
X	"Field Worker",
X	"Investigator",
X	"Investigator",
X	"Exhumer",
X	"Exhumer",
X	"Excavator",
X	"Excavator",
X	"Spelunker",
X	"Spelunker",
X	"Speleologist",
X	"Speleologist",
X	"Collector",
X	"Collector",
X	"Curator",
X	"Curator"
X};
X
Xstatic const char NEARDATA *healer_ranks[] = {
X	"Pre-Med",
X	"Pre-Med",
X	"Med Student",
X	"Med Student",
X	"Medic",
X	"Medic",
X	"Intern",
X	"Intern",
X	"Doctor",
X	"Doctor",
X	"Physician",
X	"Physician",
X	"Specialist",
X	"Specialist",
X	"Surgeon",
X	"Surgeon",
X	"Chief Surgeon",
X	"Chief Surgeon"
X};
X
Xstatic const char NEARDATA *barbarian_ranks[] = {
X	"Plunderer",
X	"Plunderess",
X	"Pillager",
X	"Pillager",
X	"Bandit",
X	"Bandit",
X	"Brigand",
X	"Brigand",
X	"Raider",
X	"Raider",
X	"Reaver",
X	"Reaver",
X	"Slayer",
X	"Slayer",
X	"Chieftain",
X	"Chieftainess",
X	"Conqueror",
X	"Conqueress"
X};
X
Xstatic const char NEARDATA *ninja_ranks[] = {
X	"Chigo",
X	"Chigo",
X	"Bushi",
X	"Bushi",
X	"Genin",
X	"Genin",
X	"Genin",
X	"Genin",
X	"Chunin",
X	"Chunin",
X	"Chunin",
X	"Chunin",
X	"Jonin",
X	"Jonin",
X	"Jonin",
X	"Jonin",
X	"Jonin",
X	"Jonin",
X};
X
Xstatic const char NEARDATA *elf_ranks[] = {
X	"Edhel",
X	"Elleth",
X	"Edhel",
X	"Elleth", 	/* elf-maid */
X	"Ohtar", 	/* warrior */
X	"Ohtie",
X	"Kano", 	/* commander (Q.) ['a] */
X	"Kanie", 	/* educated guess, until further research- SAC */
X	"Arandur", 	/* king's servant, minister (Q.) - educated guess */
X	"Aranduriel", 	/* educated guess */
X	"Hir", 		/* lord (S.) */
X	"Hiril", 	/* lady (S.) ['ir] */
X	"Aredhel", 	/* noble elf (S.) */
X	"Arwen", 	/* noble maiden (S.) */
X	"Ernil", 	/* prince (S.) */
X	"Elentariel", 	/* elf-maiden (Q.) */
X	"Elentar", 	/* Star-king (Q.) */
X	"Elentari", 	/* Star-queen (Q.) */ /* Elbereth (S.) */
X};
X
X#endif /* OVL1 */
X
XSTATIC_DCL const char **NDECL(rank_array);
X
X#ifdef OVL1
X
XSTATIC_OVL const char **
Xrank_array() {
X	register const char **ranks;
X
X	switch(pl_character[0]) {
X		case 'A':  ranks = archeo_ranks; break;
X		case 'B':  ranks = barbarian_ranks; break;
X		case 'C':  ranks = nomad_ranks; break;
X		case 'E':  ranks = elf_ranks; break;
X		case 'H':  ranks = healer_ranks; break;
X		case 'K':  ranks = knight_ranks; break;
X		case 'P':  ranks = priest_ranks; break;
X		case 'R':  ranks = thief_ranks; break;
X		case 'S':  ranks = ninja_ranks; break;
X		case 'T':  ranks = tourist_ranks; break;
X		case 'V':  ranks = fighter_ranks; break;
X		case 'W':  ranks = mage_ranks; break;
X		default:   ranks = 0; break;
X	}
X	return(ranks);
X}
X
X#endif /* OVL1 */
X
XSTATIC_DCL const char *NDECL(rank);
X
X#ifdef OVL1
X
XSTATIC_OVL const char *
Xrank() {
X	register int place;
X	register const char **ranks = rank_array();
X
X	if(u.ulevel < 3) place = 0;
X	else if(u.ulevel <  6) place =  2;
X	else if(u.ulevel < 10) place =  4;
X	else if(u.ulevel < 14) place =  6;
X	else if(u.ulevel < 18) place =  8;
X	else if(u.ulevel < 22) place = 10;
X	else if(u.ulevel < 26) place = 12;
X	else if(u.ulevel < 30) place = 14;
X	else place = 16;
X	if(flags.female) place++;
X
X	if (!!ranks) return(ranks[place]);
X	return(pl_character);
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xvoid
Xmax_rank_sz() {
X	register int i, maxr = 0;
X	register const char **ranks = rank_array();
X
X	if (!!ranks) {
X		for(i = flags.female; i < 18; i += 2)
X			if(strlen(ranks[i]) > maxr) maxr = strlen(ranks[i]);
X		mrank_sz = maxr;
X	}
X	else mrank_sz = strlen(pl_character);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xstatic void
Xfillbot(row,oldbot,newbot)
Xint row;
Xchar *oldbot, *newbot;
X{
X	register char *ob = oldbot, *nb = newbot;
X	register int i;
X	int fillcol;
X
X	fillcol = min(CO, MAXCO-1);
X
X	/* compress in case line too long */
X	if(strlen(newbot) >= fillcol) {
X		register char *bp0 = newbot, *bp1 = newbot;
X
X		do {
X#ifdef CLIPPING
X			if(*bp0 != ' ' || bp0[1] != ' ')
X#else
X			if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
X#endif
X				*bp1++ = *bp0;
X		} while(*bp0++);
X	}
X	newbot[fillcol] = '\0';
X
X	for(i = 1; i < fillcol; i++) {
X		if(!*nb) {
X			if(*ob || flags.botlx) {
X				/* last char printed may be in middle of line */
X				curs((int)strlen(newbot)+1,row);
X				cl_end();
X			}
X			break;
X		}
X		if(*ob != *nb) {
X			curs(i,row);
X			(void) putchar(*nb);
X			curx++;
X		}
X		if(*ob) ob++;
X		nb++;
X	}
X	Strcpy(oldbot, newbot);
X}
X
Xstatic void
Xbot1()
X{
X	register int i,j;
X
X#ifdef CLIPPING
X	if (CO > 59) {
X#endif
X	Strcpy(newbot1, plname);
X	if('a' <= newbot1[0] && newbot1[0] <= 'z') newbot1[0] += 'A'-'a';
X	newbot1[10] = 0;
X	Sprintf(eos(newbot1)," the ");
X#ifdef POLYSELF
X	if (u.mtimedone) {
X		char mbot[BUFSZ];
X		int k = 0;
X
X		Strcpy(mbot, mons[u.umonnum].mname);
X		while(mbot[k] != 0) {
X		    if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) &&
X					'a' <= mbot[k] && mbot[k] <= 'z')
X			mbot[k] += 'A' - 'a';
X		    k++;
X		}
X		Sprintf(eos(newbot1), mbot);
X	} else
X		Sprintf(eos(newbot1), rank());
X#else
X	Sprintf(eos(newbot1), rank());
X#endif
X	Sprintf(eos(newbot1),"  ");
X	i = mrank_sz + 15;
X	j = strlen(newbot1);
X	if((i - j) > 0)
X	      do { Sprintf(eos(newbot1)," "); /* pad with spaces */
X		   i--;
X	      } while((i - j) > 0);
X#ifdef CLIPPING
X	}
X	else
X		*newbot1 = 0;
X#endif
X	if(ACURR(A_STR)>18) {
X		if(ACURR(A_STR)>118)
X		    Sprintf(eos(newbot1),"St:%2d ",ACURR(A_STR)-100);
X		else if(ACURR(A_STR)<118)
X		    Sprintf(eos(newbot1), "St:18/%02d ",ACURR(A_STR)-18);
X		else
X		    Sprintf(eos(newbot1),"St:18/** ");
X	} else
X		Sprintf(eos(newbot1), "St:%-1d ",ACURR(A_STR));
X	Sprintf(eos(newbot1),
X		"Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
X		ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA));
X	Sprintf(eos(newbot1), (u.ualigntyp == U_CHAOTIC) ? "  Chaotic" :
X			(u.ualigntyp == U_NEUTRAL) ? "  Neutral" : "  Lawful");
X#ifdef SCORE_ON_BOTL
X	Sprintf(eos(newbot1)," S:%lu"
X	    ,(u.ugold - u.ugold0 > 0 ? u.ugold - u.ugold0 : 0)
X	    + u.urexp + (50 * maxdlevel)
X	    + (maxdlevel > 20? 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20) :0));
X#endif
X#ifdef CLIPPING
X	fillbot(min(LI-1, ROWNO+2), oldbot1, newbot1);
X#else
X	fillbot(ROWNO+2, oldbot1, newbot1);
X#endif
X}
X
Xstatic void
Xbot2()
X{
X#ifdef ENDGAME
X	if(dlevel == ENDLEVEL)
X		Sprintf(newbot2, "EndLevel ");
X	else
X#endif
X#ifdef SPELLS
X		Sprintf(newbot2, "Dlvl:%-2d ", dlevel);
X#else
X		Sprintf(newbot2, "Level:%-1d ", dlevel);
X#endif
X	Sprintf(eos(newbot2),
X#ifdef SPELLS
X		"G:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d",
X		u.ugold,
X# ifdef POLYSELF
X		u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
X		u.uen, u.uenmax, u.uac);
X# else
X		u.uhp, u.uhpmax, u.uen, u.uenmax, u.uac);
X# endif
X#else
X		"Gold:%-1lu HP:%d(%d) AC:%-1d",
X		u.ugold,
X# ifdef POLYSELF
X		u.mtimedone ? u.mh : u.uhp, u.mtimedone ? u.mhmax : u.uhpmax,
X		u.uac);
X# else
X		u.uhp, u.uhpmax, u.uac);
X# endif
X#endif
X#ifdef POLYSELF
X	if (u.mtimedone)
X		Sprintf(eos(newbot2), " HD:%d", mons[u.umonnum].mlevel);
X	else
X#endif
X#ifdef EXP_ON_BOTL
X	Sprintf(eos(newbot2), " Xp:%u/%-1ld", u.ulevel,u.uexp);
X#else
X	Sprintf(eos(newbot2), " Exp:%u", u.ulevel);
X#endif
X	if(flags.time)
X	    Sprintf(eos(newbot2), " T:%ld", moves);
X	if(strcmp(hu_stat[u.uhs], "        ")) {
X		Sprintf(eos(newbot2), " ");
X		Strcat(newbot2, hu_stat[u.uhs]);
X	}
X	if(Confusion)	   Sprintf(eos(newbot2), " Conf");
X	if(Sick)	   Sprintf(eos(newbot2), " Sick");
X	if(Blind)	   Sprintf(eos(newbot2), " Blind");
X	if(Stunned)	   Sprintf(eos(newbot2), " Stun");
X	if(Hallucination)  Sprintf(eos(newbot2), " Hallu");
X#ifdef CLIPPING
X	fillbot(min(LI, ROWNO+3), oldbot2, newbot2);
X#else
X	fillbot(ROWNO+3, oldbot2, newbot2);
X#endif
X}
X
Xvoid
Xbot() {
Xregister char *ob1 = oldbot1, *ob2 = oldbot2;
X	if(flags.botlx) *ob1 = *ob2 = 0;
X	bot1();
X	bot2();
X	flags.botl = flags.botlx = 0;
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xmstatusline(mtmp)
Xregister struct monst *mtmp;
X{
X#if defined(ALTARS) && defined(THEOLOGY)
X	int align = mtmp->ispriest
X		? ((EPRI(mtmp)->shralign & ~A_SHRINE)-1) :
X		mtmp->data->maligntyp;
X#else
X	int align = mtmp->data->maligntyp;
X#endif
X	pline("Status of %s (%s): ", mon_nam(mtmp),
X		(align <= -1) ? "chaotic" :
X		align ? "lawful" : "neutral");
X	pline("Level %d  Gold %lu  HP %d(%d)",
X	    mtmp->m_lev, mtmp->mgold, mtmp->mhp, mtmp->mhpmax);
X	pline("AC %d%s%s", mtmp->data->ac,
X	    mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? ", tame" : "");
X}
X
Xvoid
Xustatusline()
X{
X	pline("Status of %s (%s%s):", plname,
X		(u.ualign > 3) ? "stridently " :
X		(u.ualign == 3) ? "" :
X		(u.ualign >= 1) ? "haltingly " :
X		(u.ualign == 0) ? "nominally " :
X				"insufficiently ",
X		(u.ualigntyp == U_CHAOTIC) ? "chaotic" :
X		u.ualigntyp ? "lawful" : "neutral");
X	pline("Level %d  Gold %lu  HP %d(%d)  AC %d",
X# ifdef POLYSELF
X		u.mtimedone ? mons[u.umonnum].mlevel : u.ulevel,
X		u.ugold, u.mtimedone ? u.mh : u.uhp,
X		u.mtimedone ? u.mhmax : u.uhpmax, u.uac);
X# else
X		u.ulevel, u.ugold, u.uhp, u.uhpmax, u.uac);
X# endif
X}
X
Xvoid
Xcls()
X{
X	extern xchar tlx, tly;
X
X	if(flags.toplin == 1)
X		more();
X	flags.toplin = 0;
X
X	clear_screen();
X
X	tlx = tly = 1;
X
X	flags.botlx = 1;
X}
X
X#endif /* OVLB */
X#ifdef OVL2
X
Xchar
Xrndmonsym()
X{
X	return(mons[rn2(NUMMONS - 1)].mlet);
X}
X
X/*
X * we don't use objsyms here because (someday) objsyms may be
X * user programmable
X */
X
Xstatic const char NEARDATA rndobs[] = {
X	WEAPON_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM,
X#ifdef SPELLS
X	SPBOOK_SYM,
X#endif
X	RING_SYM, AMULET_SYM, FOOD_SYM, TOOL_SYM, GEM_SYM, GOLD_SYM, ROCK_SYM };
X
Xchar
Xrndobjsym()
X{
X	return rndobs[rn2(SIZE(rndobs))];
X}
X
Xstatic const char NEARDATA *hcolors[] = {
X			"ultraviolet", "infrared", "hot pink", "psychedelic",
X			"bluish-orange", "reddish-green", "dark white",
X			"light black", "loud", "salty", "sweet", "sour",
X			"bitter", "luminescent", "striped", "polka-dotted",
X			"square", "round", "triangular", "brilliant",
X			"navy blue", "cerise", "chartreuse", "mauve",
X			"lime green", "copper", "sea green", "spiral",
X			"swirly", "blotchy", "fluorescent green",
X			"burnt orange", "indigo", "amber", "tan",
X			"sky blue-pink", "lemon yellow", "off-white",
X			"paisley", "plaid", "argyle", "incandescent"};
X
Xconst char *
Xhcolor()
X{
X	return hcolors[rn2(SIZE(hcolors))];
X}
X
X#endif /* OVL2 */
X#ifdef OVL0
X
X/*ARGSUSED*/
XSTATIC_OVL void
Xhilite(x, y, let, typ)
Xint x, y;
Xuchar let, typ;
X{
X#ifdef TEXTCOLOR
X	boolean colorit;
X#endif
X	if (let == ' '
X#if !defined(MSDOS) && !defined(MACOS)
X	    || !flags.standout
X#endif
X	    ) {
X		/* don't hilite spaces; it's pointless colorwise,
X		   and also hilites secret corridors and dark areas. -3. */
X		g_putch(let);
X		return;
X	}
X
X	if (!typ) {
X		if (let == GOLD_SYM)
X			typ = AT_GLD;
X		else if (index(obj_symbols, (char) let) != NULL
X			 || let == S_MIMIC_DEF)
X			/* is an object */
X			typ = AT_OBJ;
X		else if (vism_at(x, y))
X			/* is a monster */
X			typ = AT_MON;
X	}
X#ifdef TEXTCOLOR
X# ifdef REINCARNATION
X	colorit = flags.use_color && dlevel != rogue_level;
X# else
X	colorit = flags.use_color;
X# endif
X	if (colorit) {
X	    struct monst *mtmp;
X
X	    switch (typ) {
X		case AT_MON:
X		    switch (let) {
X			case S_MIMIC_DEF:
X			    typ = HI_OBJ;
X			    break;
X		        default:
X			    if (u.ux == x && u.uy == y && u.usym == let)
X				typ = uasmon->mcolor;
X			    else if (mtmp = m_at(x, y))
X			        typ = mtmp->m_ap_type ?
X					mimic_color(mtmp) :
X					mtmp->data->mcolor;
X			    else
X				typ = 0;
X		    }
X		    break;
X		case AT_OBJ:
X		    { struct obj *otmp;
X
X		    if (let == GOLD_SYM)
X			typ = HI_GOLD;
X		    else if ((otmp = level.objects[x][y]) && 
X			   let == objects[otmp->otyp].oc_olet) {
X			if (otmp->otyp == CORPSE ||
X				otmp->otyp == DRAGON_SCALE_MAIL)
X			    typ = mons[otmp->corpsenm].mcolor;
X			else
X			    typ = objects[level.objects[x][y]->otyp].oc_color;
X		     } else
X			typ = mimic_color(m_at(x, y));
X		    }
X		    break;
X		case AT_MAP:
X		    if ( ((let == POOL_SYM && IS_POOL(levl[x][y].typ))
X#ifdef FOUNTAINS
X		    || (let == FOUNTAIN_SYM && IS_FOUNTAIN(levl[x][y].typ))
X#endif
X		     ) && hilites[BLUE] != HI)
X
X			typ = BLUE;
X#ifdef THRONES
X		    else if (let == THRONE_SYM && IS_THRONE(levl[x][y].typ)
X				&& hilites[HI_GOLD] != HI)
X			typ = HI_GOLD;
X#endif
X		    else if (levl[x][y].typ == ROOM && levl[x][y].icedpool
X				&& hilites[CYAN] != HI)
X			typ = CYAN;
X		    else
X			typ = 0;
X		    break;
X		case AT_ZAP:
X		    typ = HI_ZAP;
X		    break;
X		}
X	}
X	if (typ && colorit)
X		xputs(hilites[Hallucination ? rn2(MAXCOLORS) : typ]);
X	else
X#endif
X#ifdef REINCARNATION
X	if (typ == AT_MON && dlevel != rogue_level) revbeg();
X#else
X	if (typ == AT_MON) revbeg();
X#endif
X	g_putch(let);
X
X#ifdef TEXTCOLOR
X	if (typ && colorit) xputs(HE); else
X#endif
X#ifdef REINCARNATION
X	if (typ == AT_MON && dlevel != rogue_level) m_end();
X#else
X	if (typ == AT_MON) m_end();
X#endif
X}
X
X#endif /* OVL0 */
X#ifdef OVL2
X
X/*
X * find the appropriate symbol for printing a mimic
X */
X
Xuchar
Xmimic_appearance(mon)
Xstruct monst *mon;
X{
X	switch(mon->m_ap_type) {
X	case M_AP_NOTHING:
X		return mon->data->mlet;
X	case M_AP_FURNITURE:
X		return showsyms[mon->mappearance];
X	case M_AP_OBJECT:
X		return objects[mon->mappearance].oc_olet;
X	case M_AP_MONSTER:
X		return mons[mon->mappearance].mlet;
X	case M_AP_GOLD:
X		return GOLD_SYM;
X	default:
X		impossible("Monster mimicking %d", mon->m_ap_type);
X		return 0;
X	}
X/*NOTREACHED*/
X}
X
X#ifdef TEXTCOLOR
X/* pick an appropriate color for a mimic imitating an object */
X
XSTATIC_OVL uchar
Xmimic_color(mtmp)
Xstruct monst *mtmp;
X{
X	if (!mtmp)
X		return 0;
X	switch (mtmp->m_ap_type) {
X	case M_AP_NOTHING:
X		return mtmp->data->mcolor;
X	case M_AP_FURNITURE:
X# ifdef FOUNTAINS
X		if (mtmp->mappearance == S_fountain && hilites[BLUE] != HI)
X			return BLUE;
X# endif
X		return 0;
X	case M_AP_OBJECT:
X		return objects[mtmp->mappearance].oc_color;
X	case M_AP_MONSTER:
X		return mons[mtmp->mappearance].mcolor;
X	case M_AP_GOLD:
X		return HI_GOLD;
X	default:
X		return 0;
X	}
X}
X#endif
X
X#endif /* OVL2 */
END_OF_FILE
if test 29052 -ne `wc -c <'src/pri.c'`; then
    echo shar: \"'src/pri.c'\" unpacked with wrong size!
fi
# end of 'src/pri.c'
fi
echo shar: End of archive 31 \(of 56\).
cp /dev/null ark31isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 56 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0