[comp.sources.games] v02i010: nethack - display oriented dungeons & dragons, Part10/16

games-request@tekred.TEK.COM (07/28/87)

Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 2, Issue 10
Archive-name: nethack/Part10



#! /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 10 (of 16)."
# Contents:  gen.h monmove.c pcmain.c topten.c vault.c wizard.c
# Wrapped by billr@tekred on Tue Jul 28 09:49:38 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f gen.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"gen.h\"
else
echo shar: Extracting \"gen.h\" \(446 characters\)
sed "s/^X//" >gen.h <<'END_OF_gen.h'
X/*	SCCS Id: @(#)gen.h	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* gen.h version 1.0.1: added ONCE flag */
X
Xstruct gen {
X	struct gen *ngen;
X	xchar gx,gy;
X	unsigned gflag;		/* 037: trap type; 040: SEEN flag */
X				/* 0100: ONCE only */
X#define	TRAPTYPE	037
X#define	SEEN	040
X#define	ONCE	0100
X};
Xextern struct gen *fgold, *ftrap;
Xstruct gen *g_at();
X#define newgen()	(struct gen *) alloc(sizeof(struct gen))
END_OF_gen.h
if test 446 -ne `wc -c <gen.h`; then
    echo shar: \"gen.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f monmove.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"monmove.c\"
else
echo shar: Extracting \"monmove.c\" \(10327 characters\)
sed "s/^X//" >monmove.c <<'END_OF_monmove.c'
X/*	SCCS Id: @(#)monmove.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* monmove.c - version 1.0 */
X
X#include "hack.h"
X#include "mfndpos.h"
X#define	NULL	(char *) 0
X
Xextern int warnlevel;	/* defined in mon.c */
X
Xdochugw(mtmp) register struct monst *mtmp; {
Xregister x = mtmp->mx;
Xregister y = mtmp->my;
Xregister d = dochug(mtmp);
Xregister dd;
X	if(!d)		/* monster still alive */
X	if(Warning)
X	if(!mtmp->mpeaceful)
X	if(mtmp->data->mlevel > warnlevel)
X	if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))
X	if(dd < 100)
X	if(!canseemon(mtmp))
X		warnlevel = mtmp->data->mlevel;
X	return(d);
X}
X
X/* returns 1 if monster died moving, 0 otherwise */
Xdochug(mtmp)
Xregister struct monst *mtmp;
X{
X	register struct permonst *mdat;
X	register tmp, nearby, scared, onscary;
X
X	if(mtmp->cham && !rn2(6))
X		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
X	mdat = mtmp->data;
X	if(mdat->mlevel < 0)
X		panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);
X
X	/* regenerate monsters */
X	if((!(moves%20) || index(MREGEN, mdat->mlet)) &&
X	    mtmp->mhp < mtmp->mhpmax)
X		mtmp->mhp++;
X
X	if(mtmp->mfroz) {
X		if (Hallucination) pmon(mtmp);
X		return(0);	/* frozen monsters don't do anything */
X	}
X
X	if(mtmp->msleep)	/* there is a chance we will wake it */
X		if(!disturb(mtmp)) return(0);
X
X	/* not frozen or sleeping: wipe out texts written in the dust */
X	wipe_engr_at(mtmp->mx, mtmp->my, 1);
X
X	/* confused monsters get unconfused with small probability */
X	if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
X
X	/* some monsters teleport */
X	if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){
X		rloc(mtmp);
X		return(0);
X	}
X	if(mdat->mmove < rnd(6)) return(0);
X
X	/* fleeing monsters might regain courage */
X	if(mtmp->mflee && !mtmp->mfleetim
X	    && mtmp->mhp == mtmp->mhpmax && !rn2(25))
X		mtmp->mflee = 0;
X
X	nearby = (dist(mtmp->mx, mtmp->my) < 3);
X	onscary = (sengr_at("Elbereth", u.ux, u.uy) ||
X			sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy));
X	scared = (nearby && onscary && !mtmp->mtame && mtmp->mcansee);
X	if(scared && !mtmp->mflee) {
X		mtmp->mflee = 1;
X		mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X	}
X
X	if(!nearby ||
X		mtmp->mflee || scared ||
X		mtmp->mconf ||
X		(mtmp->minvis && !rn2(3)) ||
X#ifndef KOPS
X		(index("BIuy", mdat->mlet) && !rn2(4)) ||
X#else
X		(index("KBIuy", mdat->mlet) && !rn2(4)) ||
X#endif
X		(mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||
X		(!mtmp->mcansee && !rn2(4)) ||
X		mtmp->mpeaceful
X	   ) {
X		tmp = m_move(mtmp,0);	/* 2: monster died moving */
X		if(tmp == 2 || (tmp && mdat->mmove <= 12))
X			return(tmp == 2);
X
X		if(Hallucination && tmp==0) pmon(mtmp);
X/* If 0, this means the monster didn't move.  During hallucination, its
X   appearance should still change. */
X
X#ifdef HARD
X		/* Without this line, fast monsters don't hit you when they've
X		 * caught up to you. -dgk
X		 */
X		nearby = (dist(mtmp->mx, mtmp->my) < 3);
X		scared = (nearby && onscary);
X		if(scared && !mtmp->mflee) {
X			mtmp->mflee = 1;
X			mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X		}
X#endif
X	}
X#ifdef HARD	/* Demonic Blackmail!!! */
X	if(mdat->mlet == '&' && mtmp->mpeaceful && !mtmp->mtame)
X		if(demon_talk(mtmp))
X			 return(1);	/* you paid it off */
X#endif
X	if(!index("Ea", mdat->mlet) && nearby &&
X	 !mtmp->mpeaceful && u.uhp > 0 && !scared) {
X		if(mhitu(mtmp))
X			return(1);	/* monster died (e.g. 'y' or 'F') */
X	}
X	/* extra movement for fast monsters */
X	if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);
X	return(tmp == 2);
X}
X
Xm_move(mtmp,after)
Xregister struct monst *mtmp;
X{
X#ifndef REGBUG
X	register
X#endif
X		 struct monst *mtmp2;
X#ifndef REGBUG
X	register
X#endif
X		int nx,ny,omx,omy,appr,nearer,cnt,i,j;
X	xchar gx,gy,nix,niy,chcnt;
X	schar chi;
X	boolean likegold, likegems, likeobjs;
X#ifdef KAA
X	boolean likerock;
X#endif
X	char msym = mtmp->data->mlet;
X	schar mmoved = 0;	/* not strictly nec.: chi >= 0 will do */
X	coord poss[9];
X	long info[9];
X
X	if(mtmp->mfroz || mtmp->msleep)
X		return(0);
X	if(mtmp->mtrapped) {
X		i = mintrap(mtmp);
X		if(i == 2) return(2);	/* he died */
X		if(i == 1) return(0);	/* still in trap, so didnt move */
X	}
X	if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))
X		return(0);		/* do not leave hiding place */
X
X#ifndef NOWORM
X	if(mtmp->wormno)
X		goto not_special;
X#endif
X
X	/* my dog gets a special treatment */
X	if(mtmp->mtame) {
X		return( dog_move(mtmp, after) );
X	}
X
X	/* likewise for shopkeeper */
X	if(mtmp->isshk) {
X		mmoved = shk_move(mtmp);
X		if(mmoved >= 0)
X			goto postmov;
X		mmoved = 0;		/* follow player outside shop */
X	}
X
X	/* and for the guard */
X	if(mtmp->isgd) {
X		mmoved = gd_move();
X		goto postmov;
X	}
X
X/* teleport if that lies in our nature ('t') or when badly wounded ('1') */
X	if((msym == 't' && !rn2(5))
X	|| (msym == '1' && (mtmp->mhp < 7 || (!xdnstair && !rn2(5))
X		|| levl[u.ux][u.uy].typ == STAIRS))) {
X		if(mtmp->mhp < 7 || (msym == 't' && rn2(2)))
X			rloc(mtmp);
X		else
X			mnexto(mtmp);
X		mmoved = 1;
X		goto postmov;
X	}
X
X	/* spit fire ('D') or use a wand ('1') when appropriate */
X#ifdef DGKMOD
X	/* Add arrow and bolt throwing monsters */
X	if (index(
X# ifdef KAA
X#  ifdef KOPS
X		"D1OKC9",
X#  else
X		"D1KC9",
X#  endif
X# else
X#  ifdef KOPS
X		"D1OKC",
X#  else
X		"D1KC",
X#  endif
X# endif
X			  msym))	
X
X		if (!inrange(mtmp))	/* inrange returns 1 if OK for mon */
X			return(0);	/* to move after it zaps or throws */
X#else
X	if(index("D1", msym))
X		inrange(mtmp);
X#endif
X
X	if(msym == 'U' && !mtmp->mcan && canseemon(mtmp) &&
X	    mtmp->mcansee && rn2(5)) {
X		if(!Confusion)
X			pline("%s's gaze has confused you!", Monnam(mtmp));
X		else
X			pline("You are getting more and more confused.");
X		if(rn2(3)) mtmp->mcan = 1;
X		HConfusion += d(3,4);		/* timeout */
X	}
Xnot_special:
X	if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
X	appr = 1;
X	if(mtmp->mflee) appr = -1;
X	if(mtmp->mconf || Invis ||  !mtmp->mcansee ||
X		(index("BIy", msym) && !rn2(3)))
X		appr = 0;
X	omx = mtmp->mx;
X	omy = mtmp->my;
X	gx = u.ux;
X	gy = u.uy;
X	if(msym == 'L' && appr == 1 && mtmp->mgold > u.ugold)
X		appr = -1;
X
X	/* random criterion for 'smell' or track finding ability
X	   should use mtmp->msmell or sth
X	 */
X	if(msym == '@' ||
X	  ('a' <= msym && msym <= 'z')) {
X	extern coord *gettrack();
X	register coord *cp;
X	schar mroom;
X		mroom = inroom(omx,omy);
X		if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
X		    cp = gettrack(omx,omy);
X		    if(cp){
X			gx = cp->x;
X			gy = cp->y;
X		    }
X		}
X	}
X
X	/* look for gold or jewels nearby */
X#ifdef ROCKMOLE
X	likegold = (index("LODr", msym) != NULL);
X	likegems = (index("ODu", msym) != NULL);
X	likeobjs = (mtmp->mhide || msym == 'r');
X#else
X	likegold = (index("LOD", msym) != NULL);
X	likegems = (index("ODu", msym) != NULL);
X	likeobjs = mtmp->mhide;
X#endif
X#ifdef KAA
X	likerock = (msym == '9');
X#endif
X#define	SRCHRADIUS	25
X	{ xchar mind = SRCHRADIUS;		/* not too far away */
X	  register int dd;
X	  if(likegold){
X		register struct gold *gold;
X		for(gold = fgold; gold; gold = gold->ngold)
X		  if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){
X		    mind = dd;
X		    gx = gold->gx;
X		    gy = gold->gy;
X		}
X	  }
X	  if(likegems || likeobjs
X#ifdef KAA
X				  || likerock
X#endif
X	    )  {
X		register struct obj *otmp;
X		for(otmp = fobj; otmp; otmp = otmp->nobj)
X		if(likeobjs
X		   || (likegems && otmp->olet == GEM_SYM)
X#ifdef KAA
X		   || (likerock && otmp->olet == ROCK_SYM)
X#endif
X			)  {
X			if(msym != 'u' || objects[otmp->otyp].g_val != 0)
X			    if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){
X				mind = dd;
X				gx = otmp->ox;
X				gy = otmp->oy;
X			    }
X			}
X	    }
X	  if(mind < SRCHRADIUS && appr == -1) {
X		if(dist(omx,omy) < 10) {
X		    gx = u.ux;
X		    gy = u.uy;
X		} else
X		    appr = 1;
X	  }
X	}
X	nix = omx;
X	niy = omy;
X	cnt = mfndpos(mtmp,poss,info,
X		msym == 'u' ? NOTONL :
X#ifdef ROCKMOLE
X		msym == 'r' ? ALLOW_WALL :
X#endif
X		(msym == '@' || msym == '1') ? (ALLOW_SSM | ALLOW_TRAPS) :
X		index(UNDEAD, msym) ? NOGARLIC :
X#ifdef KAA
X		    (msym == '9') ? (ALLOW_ROCK | ALLOW_TRAPS) : ALLOW_TRAPS);
X#else
X		     ALLOW_TRAPS);
X#endif
X	chcnt = 0;
X	chi = -1;
X	for(i=0; i<cnt; i++) {
X		nx = poss[i].x;
X		ny = poss[i].y;
X		for(j=0; j<MTSZ && j<cnt-1; j++)
X			if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
X				if(rn2(4*(cnt-j))) goto nxti;
X#ifdef STUPID
X		/* some stupid compilers think that this is too complicated */
X		{ int d1 = DIST(nx,ny,gx,gy);
X		  int d2 = DIST(nix,niy,gx,gy);
X		  nearer = (d1 < d2);
X		}
X#else
X		nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));
X#endif
X		if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
X			!mmoved ||
X			(!appr && !rn2(++chcnt))){
X			nix = nx;
X			niy = ny;
X			chi = i;
X			mmoved = 1;
X		}
X	nxti:	;
X	}
X	if(mmoved){
X		if(info[chi] & ALLOW_M){
X			mtmp2 = m_at(nix,niy);
X			if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&
X			  hitmm(mtmp2,mtmp) == 2) return(2);
X			return(0);
X		}
X		if(info[chi] & ALLOW_U){
X		  (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);
X		  return(0);
X		}
X		mtmp->mx = nix;
X		mtmp->my = niy;
X		for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
X		mtmp->mtrack[0].x = omx;
X		mtmp->mtrack[0].y = omy;
X#ifndef NOWORM
X		if(mtmp->wormno) worm_move(mtmp);
X#endif
X	} else {
X		if(msym == 'u' && rn2(2)){
X			rloc(mtmp);
X			return(0);
X		}
X#ifndef NOWORM
X		if(mtmp->wormno) worm_nomove(mtmp);
X#endif
X	}
Xpostmov:
X	if(mmoved == 1) {
X		if(mintrap(mtmp) == 2)	/* he died */
X			return(2);
X#ifdef ROCKMOLE
X	       /* Maybe a rock mole just ate something? */
X	       if(msym == 'r' && IS_ROCK(levl[mtmp->mx][mtmp->my].typ) &&
X		  levl[mtmp->mx][mtmp->my].typ != POOL){
X		   register int pile = rnd(25);
X		   /* Just ate something. */
X		   if(levl[mtmp->mx][mtmp->my].typ == 0)
X		     levl[mtmp->mx][mtmp->my].typ = CORR;
X		   else if(IS_WALL(levl[mtmp->mx][mtmp->my].typ))
X		     levl[mtmp->mx][mtmp->my].typ = DOOR;
X		   mnewsym(mtmp->mx,mtmp->my);
X		   /* Left behind a pile? */
X		   if(pile < 5) {
X		       if(pile == 1)
X			mksobj_at(ENORMOUS_ROCK, mtmp->mx, mtmp->my);
X		      else
X			mksobj_at(ROCK, mtmp->mx, mtmp->my);
X		   }
X		  if(cansee(mtmp->mx, mtmp->my))
X		    atl(mtmp->mx,mtmp->my,fobj->olet);
X	       }
X	       /* Maybe a rock mole just ate some gold or armor? */
X	       if(msym == 'r') meatgold(mtmp);
X#endif /* ROCKMOLE /**/
X		if(likegold) mpickgold(mtmp);
X#ifdef KAA
X		if(likerock || likegems) mpickgems(mtmp);
X#else
X		if(likegems) mpickgems(mtmp);
X#endif
X		if(mtmp->mhide) mtmp->mundetected = 1;
X	}
X	pmon(mtmp);
X	return(mmoved);
X}
X
END_OF_monmove.c
if test 10327 -ne `wc -c <monmove.c`; then
    echo shar: \"monmove.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pcmain.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pcmain.c\"
else
echo shar: Extracting \"pcmain.c\" \(11187 characters\)
sed "s/^X//" >pcmain.c <<'END_OF_pcmain.c'
X/*	SCCS Id: @(#)pcmain.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* main.c - (PC) version 1.0.3 */
X
X#include <stdio.h>
X#include <signal.h>
X#include "hack.h"
X
X#ifdef QUEST
X#define	gamename	"PC NetQuest"
X#else
X#define	gamename	"PC NetHack"
X#endif
X
Xchar orgdir[PATHLEN], *getcwd();
X
Xextern struct permonst mons[CMNUM+2];
Xextern char genocided[], fut_geno[];
Xextern char *getlogin(), *getenv();
Xextern char plname[PL_NSIZ], pl_character[PL_CSIZ];
X
Xint (*afternmv)(), done1(), (*occupation)();
X
Xchar SAVEF[FILENAME];
Xchar *hname = gamename;
Xchar obuf[BUFSIZ];	/* BUFSIZ is defined in stdio.h */
Xint hackpid;		/* not used anymore, but kept in for save files */
X
Xextern char *nomovemsg;
Xextern long wailmsg;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	register int fd;
X	register char *dir;
X#ifdef MSDOS
X	static void moveloop();	/* a helper function for MSC optimizer */
X
X	/* Save current directory and make sure it gets restored when
X	 * the game is exited.
X	 */
X	int (*funcp)();
X
X	if (getcwd(orgdir, sizeof orgdir) == NULL) {
X		xputs("hack: current directory path too long\n");
X		_exit(1);
X	}
X	funcp = exit;	/* Kludge to get around LINT_ARGS of signal.
X			 * This will produce a compiler warning, but that's OK.
X			 */
X	signal(SIGINT, funcp);	/* restore original directory */
X#endif
X#ifdef DGK
X	initoptions();
X	if (!hackdir[0])
X		(void) strcpy(hackdir, orgdir);
X	dir = hackdir;
X#else
X	dir = getenv("HACKDIR");
X	if(argc > 1 && !strncmp(argv[1], "-d", 2)) {
X		argc--;
X		argv++;
X		dir = argv[0]+2;
X		if(*dir == '=' || *dir == ':') dir++;
X		if(!*dir && argc > 1) {
X			argc--;
X			argv++;
X			dir = argv[0];
X		}
X		if(!*dir)
X		    error("Flag -d must be followed by a directory name.");
X	}
X#endif /* DGK */
X
X	/*
X	 * Now we know the directory containing 'record' and
X	 * may do a prscore().
X	 */
X	if(argc > 1 && !strncmp(argv[1], "-s", 2)) {
X		chdirx(dir,0);
X		prscore(argc, argv);
X		exit(0);
X	}
X
X	/*
X	 * It seems he really wants to play.
X	 * Remember tty modes, to be restored on exit.
X	 */
X	gettty();
X	setbuf(stdout,obuf);
X	setrandom();
X	startup();
X	init_corpses();	/* initialize optional corpse names */
X	cls();
X	u.uhp = 1;	/* prevent RIP on early quits */
X	u.ux = FAR;	/* prevent nscr() */
X
X	/*
X	 * We cannot do chdir earlier, otherwise gethdate will fail.
X	 */
X	chdirx(dir,1);
X
X	/*
X	 * Process options.
X	 */
X	while(argc > 1 && argv[1][0] == '-'){
X		argv++;
X		argc--;
X		switch(argv[0][1]){
X#ifdef WIZARD
X		case 'D':
X# ifdef MSDOS
X			wizard = TRUE;
X# else
X			if(!strcmp(getlogin(), WIZARD))
X				wizard = TRUE;
X			else
X				printf("Sorry.\n");
X# endif
X			break;
X#endif
X		case 'u':
X			if(argv[0][2])
X			  (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
X			else if(argc > 1) {
X			  argc--;
X			  argv++;
X			  (void) strncpy(plname, argv[0], sizeof(plname)-1);
X			} else
X				printf("Player name expected after -u\n");
X			break;
X#ifdef DGK
X		/* Person does not want to use a ram disk
X		 */
X		case 'R':
X			ramdisk = FALSE;
X			break;
X#endif
X		default:
X			/* allow -T for Tourist, etc. */
X			(void) strncpy(pl_character, argv[0]+1,
X				sizeof(pl_character)-1);
X
X			/* printf("Unknown option: %s\n", *argv); */
X		}
X	}
X
X#ifdef DGK
X	set_lock_and_bones();
X	copybones(FROMPERM);
X#endif
X#ifdef WIZARD
X	if (wizard)
X		(void) strcpy(plname, "wizard");
X	else
X#endif
X	if (!*plname)
X		askname();
X	plnamesuffix();		/* strip suffix from name; calls askname() */
X				/* again if suffix was whole name */
X				/* accepts any suffix */
X#ifdef WIZARD
X	if(wizard) {
X		register char *sfoo;
X# ifndef DGK
X		/* lock is set in read_config_file */
X		(void) strcpy(lock,plname);
X# endif
X		if(sfoo = getenv("MAGIC"))
X			while(*sfoo) {
X				switch(*sfoo++) {
X				case 'n': (void) srand(*sfoo++);
X					break;
X				}
X			}
X		if(sfoo = getenv("GENOCIDED")){
X			if(*sfoo == '!'){
X				register struct permonst *pm = mons;
X				register char *gp = genocided;
X
X				while(pm < mons+CMNUM+2){
X					if(!index(sfoo, pm->mlet))
X						*gp++ = pm->mlet;
X					pm++;
X				}
X				*gp = 0;
X			} else
X				(void) strcpy(genocided, sfoo);
X			(void) strcpy(fut_geno, genocided);
X		}
X	}
X#endif /* WIZARD */
X	start_screen();
X#ifdef DGK
X	strncat(SAVEF, plname, 8);
X	strcat(SAVEF, ".sav");
X	cls();
X	if (saveDiskPrompt(1) && ((fd = open(SAVEF, 0)) >= 0)) {
X#else 
X	(void) sprintf(SAVEF, "save/%d%s", getuid(), plname);
X	regularize(SAVEF+5);		/* avoid . or / in name */
X	if((fd = open(SAVEF,0)) >= 0 &&
X	   (uptodate(fd) || unlink(SAVEF) == 666)) {
X#endif /* DGK */
X		(void) signal(SIGINT,done1);
X		pline("Restoring old save file...");
X		(void) fflush(stdout);
X		if(!dorecover(fd))
X			goto not_recovered;
X		pline("Hello %s, welcome to %s!", plname, hname);
X		flags.move = 0;
X	} else {
Xnot_recovered:
X#ifdef DGK
X		gameDiskPrompt();
X#endif
X		fobj = fcobj = invent = 0;
X		fmon = fallen_down = 0;
X		ftrap = 0;
X		fgold = 0;
X		flags.ident = 1;
X		init_objects();
X		u_init();
X
X		(void) signal(SIGINT,done1);
X		mklev();
X		u.ux = xupstair;
X		u.uy = yupstair;
X		(void) inshop();
X		setsee();
X		flags.botlx = 1;
X		/* Fix bug with dog not being made because a monster
X		 * was on the level 1 staircase
X		 */
X		{
X			struct monst *mtmp;
X
X			if (mtmp = m_at(u.ux, u.uy))
X				mnexto(mtmp);
X		}
X		makedog();
X		{ register struct monst *mtmp;
X		  if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp);	/* riv05!a3 */
X		}
X		seemons();
X		docrt();
X
X		/* give welcome message before pickup messages */
X		pline("Hello %s, welcome to %s!", plname, hname);
X
X		pickup(1);
X		if(!Blind) read_engr_at(u.ux,u.uy);
X		flags.move = 1;
X	}
X	flags.moonphase = phase_of_the_moon();
X	if(flags.moonphase == FULL_MOON) {
X		pline("You are lucky! Full moon tonight.");
X		if(!u.uluck) u.uluck++;
X	} else if(flags.moonphase == NEW_MOON) {
X		pline("Be careful! New moon tonight.");
X	}
X
X	initrack();
X	(void) signal(SIGINT, SIG_IGN);
X#ifdef MSDOS
X	/* Help for Microsoft optimizer.  Otherwise main is too large -dgk*/
X	moveloop();
X}
X
Xstatic void
Xmoveloop()
X{
X	char ch;
X	int abort;
X#endif /* MSDOS */
X	for(;;) {
X		if(flags.move) {	/* actual time passed */
X
X			settrack();
X
X			if(moves%2 == 0 ||
X			  (!(Fast & ~INTRINSIC) && (!Fast || rn2(3)))) {
X				extern struct monst *makemon();
X				movemon();
X				if(!rn2(70))
X				    (void) makemon((struct permonst *)0, 0, 0);
X			}
X			if(Glib) glibr();
X			timeout();
X			++moves;
X#ifdef PRAYERS
X			if (u.ublesscnt)  u.ublesscnt--;
X#endif
X#ifndef DGK
X			if(flags.time) flags.botl = 1;
X#endif
X#ifdef KAA
X			if(u.mtimedone)
X			    if(u.mh < 1) rehumanize();
X			else
X#endif
X			    if(u.uhp < 1) {
X				pline("You die...");
X				done("died");
X			    }
X			if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50){
X			    wailmsg = moves;
X#ifdef KAA
X				if(index("WEV", pl_character[0])) {
X					if (u.uhp == 1)
X					   pline("%s is about to die.", pl_character);
X					else
X					   pline("%s, your life force is running out.",
X						pl_character);
X				} else {
X#endif
X			    if(u.uhp == 1)
X			    pline("You hear the wailing of the Banshee...");
X			    else
X			    pline("You hear the howling of the CwnAnnwn...");
X#ifdef KAA
X				}
X#endif
X			}
X#ifdef KAA
X			if (u.mtimedone) {
X			    if (u.mh < u.mhmax) {
X				if (Regeneration || !(moves%20)) {
X					flags.botl = 1;
X					u.mh++;
X				}
X			    }
X			}
X#endif
X			if(u.uhp < u.uhpmax) {
X				if(u.ulevel > 9) {
X					if(HRegeneration || !(moves%3)) {
X					    flags.botl = 1;
X					    u.uhp += rnd((int) u.ulevel-9);
X					    if(u.uhp > u.uhpmax)
X						u.uhp = u.uhpmax;
X					}
X				} else if(HRegeneration ||
X					(!(moves%(22-u.ulevel*2)))) {
X					flags.botl = 1;
X					u.uhp++;
X				}
X			}
X#ifdef SPELLS
X			if ((u.uen<u.uenmax) && (!(moves%(21-u.ulevel/2)))) {
X				u.uen += rn2(u.ulevel/4 + 1) + 1;
X				if (u.uen > u.uenmax)  u.uen = u.uenmax;
X				flags.botl = 1;
X			}
X#endif
X			if(Teleportation && !rn2(85)) tele();
X			if(Searching && multi >= 0) (void) dosearch();
X			gethungry();
X			invault();
X			amulet();
X#ifdef HARD
X			if (u.udemigod) {
X
X				u.udg_cnt--;
X				if(u.udg_cnt <= 0) {
X
X					intervene();
X					u.udg_cnt = rn1(200, 50);
X				}
X			}
X#endif
X		}
X		if(multi < 0) {
X			if(!++multi){
X				pline(nomovemsg ? nomovemsg :
X					"You can move again.");
X				nomovemsg = 0;
X				if(afternmv) (*afternmv)();
X				afternmv = 0;
X			}
X		}
X
X		find_ac();
X#ifndef QUEST
X		if(!flags.mv || Blind)
X#endif
X		{
X			seeobjs();
X			seemons();
X			nscr();
X		}
X#ifdef DGK
X		if(flags.time) flags.botl = 1;
X#endif
X		if(flags.botl || flags.botlx) bot();
X
X		flags.move = 1;
X
X		if(multi >= 0 && occupation) {
X#ifdef DGK
X			abort = 0;
X			if (kbhit()) {
X				if ((ch = getchar()) == ABORT)
X					abort++;
X				else
X					pushch(ch);
X			}
X			if (abort || monster_nearby())
X				stop_occupation();
X			else if ((*occupation)() == 0)
X				occupation = 0;
X			if (!(++occtime % 7))
X				(void) fflush(stdout);
X#else
X			if (monster_nearby())
X				stop_occupation();
X			else if ((*occupation)() == 0)
X				occupation = 0;
X#endif
X			continue;
X		}
X
X		if(multi > 0) {
X#ifdef QUEST
X			if(flags.run >= 4) finddir();
X#endif
X			lookaround();
X			if(!multi) {	/* lookaround may clear multi */
X				flags.move = 0;
X				continue;
X			}
X			if(flags.mv) {
X				if(multi < COLNO && !--multi)
X					flags.mv = flags.run = 0;
X				domove();
X			} else {
X				--multi;
X				rhack(save_cm);
X			}
X		} else if(multi == 0) {
X			rhack((char *) 0);
X		}
X		if(multi && multi%7 == 0)
X			(void) fflush(stdout);
X	}
X}
X
X#ifndef DGK
X/* This function is unnecessary and incompatible with the #define
X * of glo(x) in config.h -dgk
X */
Xglo(foo)
Xregister foo;
X{
X	/* construct the string  xlock.n  */
X	register char *tf;
X
X	tf = lock;
X	while(*tf && *tf != '.') tf++;
X	(void) sprintf(tf, ".%d", foo);
X}
X#endif
X
X/*
X * plname is filled either by an option (-u Player  or  -uPlayer) or
X * explicitly (-w implies wizard) or by askname.
X * It may still contain a suffix denoting pl_character.
X */
Xaskname(){
Xregister int c,ct;
X	printf("\nWho are you? ");
X	(void) fflush(stdout);
X	ct = 0;
X	while((c = getchar()) != '\n'){
X#ifdef MSDOS
X		msmsg("%c", c);
X#endif
X		if(c == EOF) error("End of input\n");
X		/* some people get confused when their erase char is not ^H */
X		if(c == '\010') {
X			if(ct) ct--;
X			continue;
X		}
X		if(c != '-')
X		if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
X		if(ct < sizeof(plname)-1) plname[ct++] = c;
X	}
X	plname[ct] = 0;
X	if(ct == 0) askname();
X}
X
X/*VARARGS1*/
Ximpossible(s,x1,x2)
Xregister char *s;
X{
X	pline(s,x1,x2);
X	pline("Program in disorder - perhaps you'd better Quit.");
X}
X
X#ifdef CHDIR
Xchdirx(dir, wr)
Xchar *dir;
Xboolean wr;
X{
X
X	if(dir && chdir(dir) < 0) {
X		error("Cannot chdir to %s.", dir);
X	}
X
X#ifdef DGK
X	/* Change the default drive as well.
X	 */
X	chdrive(dir);
X#endif
X
X	/* warn the player if he cannot write the record file */
X	/* perhaps we should also test whether . is writable */
X	/* unfortunately the access systemcall is worthless */
X	if(wr) {
X	    register fd;
X
X	    if(dir == NULL)
X		dir = ".";
X	    if((fd = open(RECORD, 2)) < 0) {
X#ifdef DGK
X		char tmp[PATHLEN];
X
X		strcpy(tmp, dir);
X		append_slash(tmp);
X		msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
X		getreturn("to continue");
X#else
X		printf("Warning: cannot write %s/%s", dir, RECORD);
X		getret();
X#endif
X	    } else
X		(void) close(fd);
X	}
X}
X#endif /* CHDIR /**/
X
Xstop_occupation()
X{
X	if(occupation) {
X		pline("You stop %s.", occtxt);
X		occupation = 0;
X#ifdef DGK
X		multi = 0;
X		pushch(0);		
X#endif
X	}
X}
END_OF_pcmain.c
if test 11187 -ne `wc -c <pcmain.c`; then
    echo shar: \"pcmain.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f topten.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"topten.c\"
else
echo shar: Extracting \"topten.c\" \(11138 characters\)
sed "s/^X//" >topten.c <<'END_OF_topten.c'
X/*	SCCS Id: @(#)topten.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* topten.c - version 1.0 */
X
X#include <stdio.h>
X#include "hack.h"
X#define	Sprintf	(void) sprintf
Xextern char plname[], pl_character[];
Xextern char *itoa(), *ordin(), *eos();
Xextern int done_hup, done_stopprint;
X
X#define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry))
X#define	NAMSZ	10
X#define	DTHSZ	40
X#define	PERSMAX	 3
X#define	POINTSMIN	1	/* must be > 0 */
X#define	ENTRYMAX	100	/* must be >= 10 */
X#ifndef MSDOS
X#define	PERS_IS_UID		/* delete for PERSMAX per name; now per uid */
X#endif
Xstruct toptenentry {
X	struct toptenentry *tt_next;
X	long int points;
X	int level,maxlvl,hp,maxhp;
X	int uid;
X	char plchar;
X	char sex;
X	char name[NAMSZ+1];
X	char death[DTHSZ+1];
X	char date[7];		/* yymmdd */
X} *tt_head;
X
Xtopten(){
X	int uid = getuid();
X	int rank, rank0 = -1, rank1 = 0;
X	int occ_cnt = PERSMAX;
X	register struct toptenentry *t0, *t1, *tprev;
X	char *recfile = RECORD;
X#ifdef UNIX
X	char *reclock = "record_lock";
X#endif
X	int sleepct = 300;
X	FILE *rfile;
X	register flg = 0;
X	extern char *getdate();
X#ifndef DGK
X#define	HUP	if(!done_hup)
X#else
X#define
X#endif
X#ifdef UNIX
X	while(link(recfile, reclock) == -1) {
X		HUP perror(reclock);
X		if(!sleepct--) {
X			HUP puts("I give up. Sorry.");
X			HUP puts("Perhaps there is an old record_lock around?");
X			return;
X		}
X		HUP printf("Waiting for access to record file. (%d)\n",
X			sleepct);
X		HUP (void) fflush(stdout);
X		sleep(1);
X	}
X#endif
X	if(!(rfile = fopen(recfile,"r"))){
X		HUP puts("Cannot open record file!");
X		goto unlock;
X	}
X	HUP (void) putchar('\n');
X
X	/* create a new 'topten' entry */
X	t0 = newttentry();
X	t0->level = dlevel;
X	t0->maxlvl = maxdlevel;
X	t0->hp = u.uhp;
X	t0->maxhp = u.uhpmax;
X	t0->points = u.urexp;
X	t0->plchar = pl_character[0];
X	t0->sex = (flags.female ? 'F' : 'M');
X	t0->uid = uid;
X	(void) strncpy(t0->name, plname, NAMSZ);
X	(t0->name)[NAMSZ] = 0;
X	(void) strncpy(t0->death, killer, DTHSZ);
X	(t0->death)[DTHSZ] = 0;
X	(void) strcpy(t0->date, getdate());
X
X	/* assure minimum number of points */
X	if(t0->points < POINTSMIN)
X		t0->points = 0;
X
X	t1 = tt_head = newttentry();
X	tprev = 0;
X	/* rank0: -1 undefined, 0 not_on_list, n n_th on list */
X	for(rank = 1; ; ) {
X	  if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
X		t1->date, &t1->uid,
X		&t1->level, &t1->maxlvl,
X		&t1->hp, &t1->maxhp, &t1->points,
X		&t1->plchar, &t1->sex, t1->name, t1->death) != 11
X	  || t1->points < POINTSMIN)
X			t1->points = 0;
X	  if(rank0 < 0 && t1->points < t0->points) {
X		rank0 = rank++;
X		if(tprev == 0)
X			tt_head = t0;
X		else
X			tprev->tt_next = t0;
X		t0->tt_next = t1;
X		occ_cnt--;
X		flg++;		/* ask for a rewrite */
X	  } else
X		tprev = t1;
X	  if(t1->points == 0) break;
X	  if(
X#ifdef PERS_IS_UID
X	     t1->uid == t0->uid &&
X#else
X	     strncmp(t1->name, t0->name, NAMSZ) == 0 &&
X#endif
X	     t1->plchar == t0->plchar && --occ_cnt <= 0){
X		if(rank0 < 0){
X			rank0 = 0;
X			rank1 = rank;
X	HUP printf("You didn't beat your previous score of %ld points.\n\n",
X				t1->points);
X		}
X		if(occ_cnt < 0){
X			flg++;
X			continue;
X		}
X	  }
X	  if(rank <= ENTRYMAX){
X		t1 = t1->tt_next = newttentry();
X		rank++;
X	  }
X	  if(rank > ENTRYMAX){
X		t1->points = 0;
X		break;
X	  }
X	}
X	if(flg) {	/* rewrite record file */
X		(void) fclose(rfile);
X		if(!(rfile = fopen(recfile,"w"))){
X			HUP puts("Cannot write record file\n");
X			goto unlock;
X		}
X
X		if(!done_stopprint) if(rank0 > 0){
X		    if(rank0 <= 10)
X			puts("You made the top ten list!\n");
X		    else
X		printf("You reached the %d%s place on the top %d list.\n\n",
X			rank0, ordin(rank0), ENTRYMAX);
X		}
X	}
X	if(rank0 == 0) rank0 = rank1;
X	if(rank0 <= 0) rank0 = rank;
X	if(!done_stopprint) outheader();
X	t1 = tt_head;
X	for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
X	  if(flg) fprintf(rfile,"%6s %d %d %d %d %d %ld %c%c %s,%s\n",
X	    t1->date, t1->uid,
X	    t1->level, t1->maxlvl,
X	    t1->hp, t1->maxhp, t1->points,
X	    t1->plchar, t1->sex, t1->name, t1->death);
X	  if(done_stopprint) continue;
X	  if(rank > flags.end_top &&
X	    (rank < rank0-flags.end_around || rank > rank0+flags.end_around)
X	    && (!flags.end_own ||
X#ifdef PERS_IS_UID
X				  t1->uid != t0->uid ))
X#else
X				  strncmp(t1->name, t0->name, NAMSZ)))
X#endif
X		continue;
X	  if(rank == rank0-flags.end_around &&
X	     rank0 > flags.end_top+flags.end_around+1 &&
X	     !flags.end_own)
X		(void) putchar('\n');
X	  if(rank != rank0)
X		(void) outentry(rank, t1, 0);
X	  else if(!rank1)
X		(void) outentry(rank, t1, 1);
X	  else {
X		int t0lth = outentry(0, t0, -1);
X		int t1lth = outentry(rank, t1, t0lth);
X		if(t1lth > t0lth) t0lth = t1lth;
X		(void) outentry(0, t0, t0lth);
X	  }
X	}
X	if(rank0 >= rank) if(!done_stopprint)
X		(void) outentry(0, t0, 1);
X	(void) fclose(rfile);
Xunlock:	;
X#ifdef UNIX
X	(void) unlink(reclock);
X#endif
X}
X
Xoutheader() {
Xchar linebuf[BUFSZ];
Xregister char *bp;
X	(void) strcpy(linebuf, "Number Points  Name");
X	bp = eos(linebuf);
X	while(bp < linebuf + COLNO - 9) *bp++ = ' ';
X	(void) strcpy(bp, "Hp [max]");
X	puts(linebuf);
X}
X
X/* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */
Xint
Xoutentry(rank,t1,so) register struct toptenentry *t1; {
Xboolean quit = FALSE, killed = FALSE, starv = FALSE;
Xchar linebuf[BUFSZ];
X	linebuf[0] = 0;
X	if(rank) Sprintf(eos(linebuf), "%3d", rank);
X		else Sprintf(eos(linebuf), "   ");
X#ifdef DGKMOD
X	Sprintf(eos(linebuf), " %6ld %10s", t1->points, t1->name);
X#else
X	Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->name);
X#endif
X	if(t1->plchar == 'X') Sprintf(eos(linebuf), " ");
X	else Sprintf(eos(linebuf), "-%c ", t1->plchar);
X	if(!strncmp("escaped", t1->death, 7)) {
X	  if(!strcmp(" (with amulet)", t1->death+7))
X	    Sprintf(eos(linebuf), "escaped the dungeon with amulet");
X	  else
X	    Sprintf(eos(linebuf), "escaped the dungeon [max level %d]",
X	      t1->maxlvl);
X	} else {
X	  if(!strncmp(t1->death,"quit",4)) {
X	    quit = TRUE;
X	    if(t1->maxhp < 3*t1->hp && t1->maxlvl < 4)
X		Sprintf(eos(linebuf), "cravenly gave up");
X	    else
X		Sprintf(eos(linebuf), "quit");
X	  }
X	  else if(!strcmp(t1->death,"choked"))
X	    Sprintf(eos(linebuf), "choked on %s food",
X		(t1->sex == 'F') ? "her" : "his");
X	  else if(!strncmp(t1->death,"starv",5))
X	    Sprintf(eos(linebuf), "starved to death"), starv = TRUE;
X	  else Sprintf(eos(linebuf), "was killed"), killed = TRUE;
X	  Sprintf(eos(linebuf), " on%s level %d",
X	    (killed || starv) ? "" : " dungeon", t1->level);
X	  if(t1->maxlvl != t1->level)
X	    Sprintf(eos(linebuf), " [max %d]", t1->maxlvl);
X	  if(quit && t1->death[4]) Sprintf(eos(linebuf), t1->death + 4);
X	}
X	if(killed) Sprintf(eos(linebuf), " by %s%s",
X	  (!strncmp(t1->death, "trick", 5) || !strncmp(t1->death, "the ", 4))
X		? "" :
X	  index(vowels,*t1->death) ? "an " : "a ",
X	  t1->death);
X	Sprintf(eos(linebuf), ".");
X	if(t1->maxhp) {
X	  register char *bp = eos(linebuf);
X	  char hpbuf[10];
X	  int hppos;
X	  Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-");
X	  hppos = COLNO - 7 - strlen(hpbuf);
X	  if(bp <= linebuf + hppos) {
X	    while(bp < linebuf + hppos) *bp++ = ' ';
X	    (void) strcpy(bp, hpbuf);
X	    Sprintf(eos(bp), " [%d]", t1->maxhp);
X	  }
X	}
X	if(so == 0) puts(linebuf);
X	else if(so > 0) {
X	  register char *bp = eos(linebuf);
X	  if(so >= COLNO) so = COLNO-1;
X	  while(bp < linebuf + so) *bp++ = ' ';
X	  *bp = 0;
X	  standoutbeg();
X	  fputs(linebuf,stdout);
X	  standoutend();
X	  (void) putchar('\n');
X	}
X	return(strlen(linebuf));
X}
X
Xchar *
Xitoa(a) int a; {
Xstatic char buf[12];
X	Sprintf(buf,"%d",a);
X	return(buf);
X}
X
Xchar *
Xordin(n) int n; {
Xregister int d = n%10;
X	return((d==0 || d>3 || n/10==1) ? "th" : (d==1) ? "st" :
X		(d==2) ? "nd" : "rd");
X}
X
Xchar *
Xeos(s)
Xregister char *s;
X{
X	while(*s) s++;
X	return(s);
X}
X
X/*
X * Called with args from main if argc >= 0. In this case, list scores as
X * requested. Otherwise, find scores for the current player (and list them
X * if argc == -1).
X */
Xprscore(argc,argv) int argc; char **argv; {
X	extern char *hname;
X	char **players;
X	int playerct;
X	int rank;
X	register struct toptenentry *t1, *t2;
X	char *recfile = RECORD;
X	FILE *rfile;
X	register flg = 0;
X	register int i;
X#ifdef nonsense
X	long total_score = 0L;
X	char totchars[10];
X	int totcharct = 0;
X#endif
X	int outflg = (argc >= -1);
X#ifdef PERS_IS_UID
X	int uid = -1;
X#else
X	char *player0;
X#endif
X
X	if(!(rfile = fopen(recfile,"r"))){
X		puts("Cannot open record file!");
X		return;
X	}
X
X	if(argc > 1 && !strncmp(argv[1], "-s", 2)){
X		if(!argv[1][2]){
X			argc--;
X			argv++;
X		} else if(!argv[1][3] && index("CFKSTWX", argv[1][2])) {
X			argv[1]++;
X			argv[1][0] = '-';
X		} else	argv[1] += 2;
X	}
X	if(argc <= 1){
X#ifdef PERS_IS_UID
X		uid = getuid();
X		playerct = 0;
X#else
X		player0 = plname;
X		if(!*player0)
X			player0 = "hackplayer";
X		playerct = 1;
X		players = &player0;
X#endif
X	} else {
X		playerct = --argc;
X		players = ++argv;
X	}
X	if(outflg) putchar('\n');
X
X	t1 = tt_head = newttentry();
X	for(rank = 1; ; rank++) {
X	  if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
X		t1->date, &t1->uid,
X		&t1->level, &t1->maxlvl,
X		&t1->hp, &t1->maxhp, &t1->points,
X		&t1->plchar, &t1->sex, t1->name, t1->death) != 11)
X			t1->points = 0;
X	  if(t1->points == 0) break;
X#ifdef PERS_IS_UID
X	  if(!playerct && t1->uid == uid)
X		flg++;
X	  else
X#endif
X	  for(i = 0; i < playerct; i++){
X		if(strcmp(players[i], "all") == 0 ||
X		   strncmp(t1->name, players[i], NAMSZ) == 0 ||
X		  (players[i][0] == '-' &&
X		   players[i][1] == t1->plchar &&
X		   players[i][2] == 0) ||
X		  (digit(players[i][0]) && rank <= atoi(players[i])))
X			flg++;
X	  }
X	  t1 = t1->tt_next = newttentry();
X	}
X	(void) fclose(rfile);
X	if(!flg) {
X	    if(outflg) {
X		printf("Cannot find any entries for ");
X		if(playerct < 1) printf("you.\n");
X		else {
X		  if(playerct > 1) printf("any of ");
X		  for(i=0; i<playerct; i++)
X			printf("%s%s", players[i], (i<playerct-1)?", ":".\n");
X		  printf("Call is: %s -s [playernames]\n", hname);
X		}
X	    }
X	    return;
X	}
X
X	if(outflg) outheader();
X	t1 = tt_head;
X	for(rank = 1; t1->points != 0; rank++, t1 = t2) {
X		t2 = t1->tt_next;
X#ifdef PERS_IS_UID
X		if(!playerct && t1->uid == uid)
X			goto outwithit;
X		else
X#endif
X		for(i = 0; i < playerct; i++){
X			if(strcmp(players[i], "all") == 0 ||
X			   strncmp(t1->name, players[i], NAMSZ) == 0 ||
X			  (players[i][0] == '-' &&
X			   players[i][1] == t1->plchar &&
X			   players[i][2] == 0) ||
X			  (digit(players[i][0]) && rank <= atoi(players[i]))){
X			outwithit:
X				if(outflg)
X				    (void) outentry(rank, t1, 0);
X#ifdef nonsense
X				total_score += t1->points;
X				if(totcharct < sizeof(totchars)-1)
X				    totchars[totcharct++] = t1->plchar;
X#endif
X				break;
X			}
X		}
X		free((char *) t1);
X	}
X#ifdef nonsense
X	totchars[totcharct] = 0;
X
X	/* We would like to determine whether he is experienced. However,
X	   the information collected here only tells about the scores/roles
X	   that got into the topten (top 100?). We should maintain a
X	   .hacklog or something in his home directory. */
X	flags.beginner = (total_score < 6000);
X	for(i=0; i<6; i++)
X	    if(!index(totchars, "CFKSTWX"[i])) {
X		flags.beginner = 1;
X		if(!pl_character[0]) pl_character[0] = "CFKSTWX"[i];
X		break;
X	}
X#endif /* nonsense /**/
X}
END_OF_topten.c
if test 11138 -ne `wc -c <topten.c`; then
    echo shar: \"topten.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f vault.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"vault.c\"
else
echo shar: Extracting \"vault.c\" \(5920 characters\)
sed "s/^X//" >vault.c <<'END_OF_vault.c'
X/*	SCCS Id: @(#)vault.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* vault.c - version 1.0.2 */
X
X#include	"hack.h"
X#ifdef QUEST
Xsetgd(/* mtmp */) /* struct monst *mtmp; */ {}
Xgd_move() { return(2); }
Xgddead(mtmp) struct monst *mtmp; {}
Xreplgd(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {}
Xinvault(){}
X
X#else
X
X
X#include "mkroom.h"
Xextern struct monst *makemon();
X#define	FCSIZ	(ROWNO+COLNO)
Xstruct fakecorridor {
X	xchar fx,fy,ftyp;
X};
X
Xstruct egd {
X	int fcbeg, fcend;	/* fcend: first unused pos */
X	xchar gdx, gdy;		/* goal of guard's walk */
X	unsigned gddone:1;
X	struct fakecorridor fakecorr[FCSIZ];
X};
X
Xstatic struct permonst pm_guard =
X	{ "guard", '@', 12, 12, -1, 40, 4, 10, sizeof(struct egd) };
X
Xstatic struct monst *guard;
Xstatic int gdlevel;
X#define	EGD	((struct egd *)(&(guard->mextra[0])))
X
Xstatic
Xrestfakecorr()
X{
X	register fcx,fcy,fcbeg;
X	register struct rm *crm;
X
X	while((fcbeg = EGD->fcbeg) < EGD->fcend) {
X		fcx = EGD->fakecorr[fcbeg].fx;
X		fcy = EGD->fakecorr[fcbeg].fy;
X		if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
X		   m_at(fcx,fcy))
X			return;
X		crm = &levl[fcx][fcy];
X		crm->typ = EGD->fakecorr[fcbeg].ftyp;
X		if(!crm->typ) crm->seen = 0;
X		newsym(fcx,fcy);
X		EGD->fcbeg++;
X	}
X	/* it seems he left the corridor - let the guard disappear */
X	mondead(guard);
X	guard = 0;
X}
X
Xstatic
Xgoldincorridor()
X{
X	register int fci;
X
X	for(fci = EGD->fcbeg; fci < EGD->fcend; fci++)
X		if(g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
X			return(1);
X	return(0);
X}
X
Xsetgd(){
Xregister struct monst *mtmp;
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
X		guard = mtmp;
X		gdlevel = dlevel;
X		return;
X	}
X	guard = 0;
X}
X
Xinvault(){
Xregister tmp = inroom(u.ux, u.uy);
X    if(tmp < 0 || rooms[tmp].rtype != VAULT) {
X	u.uinvault = 0;
X	return;
X    }
X    if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
X	char buf[BUFSZ];
X	register x,y,dd,gx,gy;
X
X	/* first find the goal for the guard */
X	for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
X	  for(y = u.uy-dd; y <= u.uy+dd; y++) {
X	    if(y < 0 || y > ROWNO-1) continue;
X	    for(x = u.ux-dd; x <= u.ux+dd; x++) {
X	      if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
X		x = u.ux+dd;
X	      if(x < 0 || x > COLNO-1) continue;
X	      if(levl[x][y].typ == CORR) goto fnd;
X	    }
X	  }
X	}
X	impossible("Not a single corridor on this level??");
X	tele();
X	return;
Xfnd:
X	gx = x; gy = y;
X
X	/* next find a good place for a door in the wall */
X	x = u.ux; y = u.uy;
X	while(levl[x][y].typ == ROOM) {
X		register int dx,dy;
X
X		dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X		dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X		if(abs(gx-x) >= abs(gy-y))
X			x += dx;
X		else
X			y += dy;
X	}
X
X	/* make something interesting happen */
X	if(!(guard = makemon(&pm_guard,x,y))) return;
X	guard->isgd = guard->mpeaceful = 1;
X	EGD->gddone = 0;
X	gdlevel = dlevel;
X	if(!cansee(guard->mx, guard->my)) {
X		mondead(guard);
X		guard = 0;
X		return;
X	}
X
X	pline("Suddenly one of the Vault's guards enters!");
X	pmon(guard);
X	do {
X		pline("\"Hello stranger, who are you?\" - ");
X		getlin(buf);
X	} while (!letter(buf[0]));
X
X	if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
X		pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
X		mondead(guard);
X		guard = 0;
X		return;
X	}
X	clrlin();
X	pline("\"I don't know you.\"");
X	if(!u.ugold)
X	    pline("\"Please follow me.\"");
X	else {
X	    pline("\"Most likely all that gold was stolen from this vault.\"");
X	    pline("\"Please drop your gold (say d$ ) and follow me.\"");
X	}
X	EGD->gdx = gx;
X	EGD->gdy = gy;
X	EGD->fcbeg = 0;
X	EGD->fakecorr[0].fx = x;
X	EGD->fakecorr[0].fy = y;
X	EGD->fakecorr[0].ftyp = levl[x][y].typ;
X	levl[x][y].typ = DOOR;
X	EGD->fcend = 1;
X    }
X}
X
Xgd_move(){
Xregister int x,y,dx,dy,gx,gy,nx,ny,typ;
Xregister struct fakecorridor *fcp;
Xregister struct rm *crm;
X	if(!guard || gdlevel != dlevel){
X		impossible("Where is the guard?");
X		return(2);	/* died */
X	}
X	if(u.ugold || goldincorridor())
X		return(0);	/* didnt move */
X	if(dist(guard->mx,guard->my) > 1 || EGD->gddone) {
X		restfakecorr();
X		return(0);	/* didnt move */
X	}
X	x = guard->mx;
X	y = guard->my;
X	/* look around (hor & vert only) for accessible places */
X	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
X	    if(nx == x || ny == y) if(nx != x || ny != y)
X	    if(isok(nx,ny))
X	    if(!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
X		register int i;
X		for(i = EGD->fcbeg; i < EGD->fcend; i++)
X			if(EGD->fakecorr[i].fx == nx &&
X			   EGD->fakecorr[i].fy == ny)
X				goto nextnxy;
X		if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
X			goto nextnxy;
X		/* seems we found a good place to leave him alone */
X		EGD->gddone = 1;
X		if(ACCESSIBLE(typ)) goto newpos;
X		crm->typ = (typ == SCORR) ? CORR : DOOR;
X		goto proceed;
X	    }
X    nextnxy:	;
X	}
X	nx = x;
X	ny = y;
X	gx = EGD->gdx;
X	gy = EGD->gdy;
X	dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X	dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X	if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
X
X	while((typ = (crm = &levl[nx][ny])->typ) != 0) {
X	/* in view of the above we must have IS_WALL(typ) or typ == POOL */
X	/* must be a wall here */
X		if(isok(nx+nx-x,ny+ny-y) && typ != POOL &&
X		    ZAP_POS(levl[nx+nx-x][ny+ny-y].typ)){
X			crm->typ = DOOR;
X			goto proceed;
X		}
X		if(dy && nx != x) {
X			nx = x; ny = y+dy;
X			continue;
X		}
X		if(dx && ny != y) {
X			ny = y; nx = x+dx; dy = 0;
X			continue;
X		}
X		/* I don't like this, but ... */
X		crm->typ = DOOR;
X		goto proceed;
X	}
X	crm->typ = CORR;
Xproceed:
X	if(cansee(nx,ny)) {
X		mnewsym(nx,ny);
X		prl(nx,ny);
X	}
X	fcp = &(EGD->fakecorr[EGD->fcend]);
X	if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
X	fcp->fx = nx;
X	fcp->fy = ny;
X	fcp->ftyp = typ;
Xnewpos:
X	if(EGD->gddone) nx = ny = 0;
X	guard->mx = nx;
X	guard->my = ny;
X	pmon(guard);
X	restfakecorr();
X	return(1);
X}
X
Xgddead(){
X	guard = 0;
X}
X
Xreplgd(mtmp,mtmp2)
Xregister struct monst *mtmp, *mtmp2;
X{
X	if(mtmp == guard)
X		guard = mtmp2;
X}
X
X#endif /* QUEST /**/
END_OF_vault.c
if test 5920 -ne `wc -c <vault.c`; then
    echo shar: \"vault.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f wizard.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"wizard.c\"
else
echo shar: Extracting \"wizard.c\" \(11381 characters\)
sed "s/^X//" >wizard.c <<'END_OF_wizard.c'
X/*	SCCS Id: @(#)wizard.c	1.3	87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* wizard.c - version 1.0.3 */
X
X/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */
X/*	       - heavily modified to give the wiz balls.  (genat!mike)   */
X
X#include "hack.h"
Xextern struct permonst pm_wizard;
Xextern struct monst *makemon();
X
X#if defined(HARD) || defined(DGKMOD)
Xchar	nasties[] = "cdDeImoPTUVwxXz&\\,:;";
X#define WIZSHOT	    2
X#else
X#define	WIZSHOT	    6	/* one chance in WIZSHOT that wizard will try magic */
X#endif
X
X#define	BOLT_LIM    8	/* from this distance D and 1 will try to hit you */
X
Xchar wizapp[] = "@&DNPTUVXcemntx";
X
X#ifdef DGKMOD
X#define URETREATING(x,y) (movedist(u.ux,u.uy,x,y) > movedist(u.ux0,u.uy0,x,y))
Xextern char mlarge[];
X
Xmovedist(x0, x1, y0, y1)
X{
X	register int absdx, absdy;
X
X	absdx = abs(x1 - x0);
X	absdy = abs(y1 - y0);
X
X	return (absdx + absdy - min(absdx, absdy));
X}
X#endif
X
X/* If he has found the Amulet, make the wizard appear after some time */
Xamulet(){
X	register struct obj *otmp;
X	register struct monst *mtmp;
X
X	if(!flags.made_amulet || !flags.no_of_wizards)
X		return;
X	/* find wizard, and wake him if necessary */
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X	    if(mtmp->data->mlet == '1' && mtmp->msleep && !rn2(40))
X		for(otmp = invent; otmp; otmp = otmp->nobj)
X		    if(otmp->olet == AMULET_SYM && !otmp->spe) {
X			mtmp->msleep = 0;
X			if(dist(mtmp->mx,mtmp->my) > 2)
X			    pline(
X    "You get the creepy feeling that somebody noticed your taking the Amulet."
X			    );
X			return;
X		    }
X}
X
Xwiz_hit(mtmp)
Xregister struct monst *mtmp;
X{
X	/* if we have stolen or found the amulet, we disappear */
X	if(mtmp->minvent && mtmp->minvent->olet == AMULET_SYM &&
X	    mtmp->minvent->spe == 0) {
X		/* vanish -- very primitive */
X		fall_down(mtmp);
X		return(1);
X	}
X
X	/* if it is lying around someplace, we teleport to it */
X	if(!carrying(AMULET_OF_YENDOR)) {
X	    register struct obj *otmp;
X
X	    for(otmp = fobj; otmp; otmp = otmp->nobj)
X		if(otmp->olet == AMULET_SYM && !otmp->spe) {
X		    if((u.ux != otmp->ox || u.uy != otmp->oy) &&
X		       !m_at(otmp->ox, otmp->oy)) {
X
X			/* teleport to it and pick it up */
X			mtmp->mx = otmp->ox;
X			mtmp->my = otmp->oy;
X			freeobj(otmp);
X			mpickobj(mtmp, otmp);
X			pmon(mtmp);
X			return(0);
X		    }
X		    goto hithim;
X		}
X	    return(0);				/* we don't know where it is */
X	}
Xhithim:
X	if(rn2(2)) {				/* hit - perhaps steal */
X
X	    /* if hit 1/20 chance of stealing amulet & vanish
X		- amulet is on level 26 again. */
X	    if(hitu(mtmp, d(mtmp->data->damn,mtmp->data->damd))
X		&& !rn2(20) && stealamulet(mtmp))
X		;
X	}
X	else    inrange(mtmp);			/* try magic */
X	return(0);
X}
X
X#ifdef DGKMOD
X/* Check if a monster is carrying a particular item.
X */
Xstruct obj *
Xm_carrying(mtmp, type)
Xstruct monst *mtmp;
Xint type;
X{
X	register struct obj *otmp;
X
X	for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
X		if(otmp->otyp == type)
X			return(otmp);
X	return((struct obj *) 0);
X}
X
X/* Remove an item from the monster's inventory.
X */
Xm_useup(mon, obj)
Xstruct monst *mon;
Xstruct obj *obj;
X{
X	struct obj *otmp, *prev;
X
X	prev = ((struct obj *) 0);
X	for (otmp = mon->minvent; otmp; otmp = otmp->nobj) {
X		if (otmp == obj) {
X			if (prev)
X				prev->nobj = obj->nobj;
X			else
X				mon->minvent = obj->nobj;
X			free((char *) obj);
X			break;
X		}
X		prev = otmp;
X	}
X}
X
Xm_throw(x, y, dx, dy, range, obj)
Xregister int x,y,dx,dy,range;		/* direction and range */
Xregister struct obj *obj;
X{
X	register struct monst *mtmp;
X	struct objclass *oclass = &objects[obj->otyp];
X	char sym = obj->olet;
X	int damage;
X	extern char *exclam();
X
X	bhitpos.x = x;
X	bhitpos.y = y;
X
X	if(sym) tmp_at(-1, sym);	/* open call */
X	while(range-- > 0) {
X		bhitpos.x += dx;
X		bhitpos.y += dy;
X		if(mtmp = m_at(bhitpos.x,bhitpos.y)) {
X			damage = index(mlarge, mtmp->data->mlet)
X				? oclass->wldam
X				: oclass->wsdam;
X#ifdef KAA
X# ifdef KOPS
X			if(obj->otyp == CREAM_PIE) damage = 0;
X# endif
X			if(mtmp->data->ac + 8 <= rnd(20))
X				miss(oclass->oc_name, mtmp);
X			else {
X#endif
X				hit(oclass->oc_name, mtmp, exclam(damage));
X				mtmp->mhp -= damage;
X				if(mtmp->mhp < 1) {
X					pline("%s is killed!", (Blind) ? "It" : Monnam(mtmp));
X					mondied(mtmp);
X				}
X				range = 0;
X#ifdef KAA
X# ifdef KOPS
X				if(obj->otyp == CREAM_PIE) {
X
X					pline("%s is blinded by the pie.", (Blind) ? "It" : Monnam(mtmp));
X					if(mtmp->msleep) mtmp->msleep = 0;
X					setmangry(mtmp);
X					mtmp->mcansee = 0;
X					mtmp->mblinded += rnd(25);
X					if (mtmp->mblinded <= 0)
X						mtmp->mblinded = 127;
X				} else
X# endif
X				    if(obj->otyp == ENORMOUS_ROCK) {
X					mksobj_at(ENORMOUS_ROCK, bhitpos.x, bhitpos.y);
X					fobj->quan=1;
X					stackobj(fobj);
X				}
X			}
X#endif
X		}
X		if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
X			if (multi)
X				nomul(0);
X#ifdef KAA
X/* For giants throwing rocks, the rock which hits you shouldn't disappear. */
X# ifdef KOPS
X/* Cream pies must disappear if they hit or miss. */
X			{ int hit, blindinc, thitu();
X			 if (!(hit = thitu(8, (obj->otyp != CREAM_PIE) ? rnd(oclass->wldam) : 0, oclass->oc_name))
X			    && obj->otyp != CREAM_PIE
X# else
X			 if (!thitu(8, rnd(oclass->wldam), oclass->oc_name)
X# endif KOPS
X			    || obj->otyp == ENORMOUS_ROCK) {
X#else
X			 if (!thitu(8, rnd(oclass->wldam), oclass->oc_name)) {
X#endif
X				mksobj_at(obj->otyp, u.ux, u.uy);
X				fobj->quan = 1;
X				stackobj(fobj);
X			 }
X#if defined(KAA) && defined(KOPS)
X			 if(hit && obj->otyp == CREAM_PIE) {
X			    if(!Blind)	pline("Yeech! You've been creamed.");
X			    else	pline("There's something sticky all over your face.");
X			    u.ucreamed += (blindinc = rnd(25));
X			    Blind += blindinc;
X			    seeoff(0);
X			 }
X			}
X#endif
X			range = 0;
X		}
X		tmp_at(bhitpos.x, bhitpos.y);
X	}
X	tmp_at(-1, -1);
X}
X#endif
X
X/* Return 1 if it's OK for the monster to move as well as (throw,
X * zap, etc).
X */
Xinrange(mtmp)
Xregister struct monst *mtmp;
X{
X	register schar tx,ty;
X#ifdef DGKMOD
X	struct obj *otmp;
X	register xchar x, y;
X#endif
X	/* do nothing if cancelled (but make '1' say something) */
X	if(mtmp->data->mlet != '1' && mtmp->mcan) return(1);
X
X	/* spit fire only when both in a room or both in a corridor */
X	if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return(1);
X	tx = u.ux - mtmp->mx;
X	ty = u.uy - mtmp->my;
X#ifdef DGKMOD
X	if ((!tx || !ty || abs(tx) == abs(ty))	/* straight line or diagonal */
X		&& movedist(tx, 0,  ty, 0) < BOLT_LIM) {
X		/* Check if there are any dead squares between.  If so,
X		 * it won't be possible to shoot.
X		 */
X		for (x = mtmp->mx, y = mtmp->my; x != u.ux || y != u.uy;
X				x += sgn(tx), y += sgn(ty))
X			if (!ACCESSIBLE(levl[x][y].typ))
X				return(1);
X
X		switch(mtmp->data->mlet) {
X#ifdef KOPS
X		case 'O':
X#endif
X#ifdef KAA
X		case '9':
X#endif
X		case 'K':
X		case 'C':
X		/* If you're coming toward the monster, the monster
X		 * should try to soften you up with arrows.  If you're
X		 * going away, you are probably hurt or running.  Give
X		 * chase, but if you're getting too far away, throw.
X		 */
X		x = mtmp->mx;
X		y = mtmp->my;
X#ifdef KOPS
X		otmp = (mtmp->data->mlet == 'O') ? m_carrying(mtmp, DART)
X# ifdef KAA
X		       : (mtmp->data->mlet == 'K') ? m_carrying(mtmp, CREAM_PIE)
X# endif
X#else
X		otmp = (mtmp->data->mlet == 'K') ? m_carrying(mtmp, DART)
X#endif
X#ifdef KAA
X			: (mtmp->data->mlet == '9') ? m_carrying(mtmp, ENORMOUS_ROCK)
X#endif
X			: m_carrying(mtmp, CROSSBOW_BOLT);
X		if (otmp && (!URETREATING(x,y)
X			|| !rn2(BOLT_LIM - movedist(x, u.ux, y, u.uy)))) {
X				m_throw(mtmp->mx, mtmp->my, sgn(tx), sgn(ty),
X					BOLT_LIM, otmp);
X				if (!--otmp->quan )
X					m_useup(mtmp, otmp);
X				return(0);
X			}
X		break;
X#else
X	if((!tx && abs(ty) < BOLT_LIM) || (!ty && abs(tx) < BOLT_LIM)
X	    || (abs(tx) == abs(ty) && abs(tx) < BOLT_LIM)){
X	    switch(mtmp->mappearance) {
X#endif
X	    case 'D':
X		/* spit fire in the direction of @ (not nec. hitting) */
X		buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty));
X		break;
X#ifdef HARD
X	    case '&':
X		demon_hit(mtmp);
X		break;
X#endif
X	    case '1':
X		if(rn2(WIZSHOT)) break;
X		/* if you zapped wizard with wand of cancellation,
X		he has to shake off the effects before he can throw
X		spells successfully.  Sometimes they fail anyway */
X		if(mtmp->mcan ||
X#ifdef HARD
X		   rn2(4)
X#else
X		   rn2(2)
X#endif
X		   ) {
X		    if(canseemon(mtmp))
X				pline("%s makes a gesture, then curses.",
X					Monnam(mtmp));
X		    else	pline("You hear mumbled cursing.");
X
X		    if(!rn2(3)) {
X			mtmp->mspeed = 0;
X			mtmp->minvis = 0;
X		    }
X		    if(!rn2(3))	mtmp->mcan = 0;
X
X		} else {
X		    if(canseemon(mtmp)){
X			if(!rn2(6) && !Invis) {
X			    pline("%s hypnotizes you.", Monnam(mtmp));
X			    nomul(-rn2(3) + 3);	/* bug fix by ab@unido */
X			    break;
X			} else
X			    pline("%s chants an incantation.", Monnam(mtmp));
X		    } else
X			    pline("You hear a mumbled incantation.");
X		    switch(rn2(Invis ? 5 : 6)) {
X		    case 0:
X			/* create a nasty monster from a deep level */
X			nasty();
X			break;
X		    case 1:
X			pline("\"Destroy the thief, my pets!\"");
X			aggravate();	/* aggravate all the monsters */
X			/* fall into next case */
X		    case 2:
X			if (flags.no_of_wizards == 1 && rnd(5) == 0)
X			    /* if only 1 wizard, clone himself */
X			    clonewiz(mtmp);
X			break;
X		    case 3:
X			if(mtmp->mspeed == MSLOW)	mtmp->mspeed = 0;
X			else				mtmp->mspeed = MFAST;
X			break;
X		    case 4:
X			mtmp->minvis = 1;
X			break;
X		    case 5:
X			/* Only if not Invisible */
X			pline("You hear a clap of thunder!");
X			/* shoot a bolt of fire or cold, or a sleep ray */
X			buzz(-rnd(3),mtmp->mx,mtmp->my,sgn(tx),sgn(ty));
X			break;
X		    }
X		}
X	    }
X	    if(u.uhp < 1) done_in_by(mtmp);
X	}
X	return(1);
X}
X
Xaggravate()
X{
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X		mtmp->msleep = 0;
X		if(mtmp->mfroz && !rn2(5))
X			mtmp->mfroz = 0;
X	}
X}
X
Xclonewiz(mtmp)
Xregister struct monst *mtmp;
X{
X	register struct monst *mtmp2;
X
X	if(mtmp2 = makemon(PM_WIZARD, mtmp->mx, mtmp->my)) {
X		flags.no_of_wizards = 2;
X		unpmon(mtmp2);
X		mtmp2->mappearance = wizapp[rn2(sizeof(wizapp)-1)];
X		pmon(mtmp2);
X	}
X}
X
Xnasty() {
X
X#ifdef HARD
X	register struct monst	*mtmp;
X	struct monst	*mkmon_at();
X	register int	i, nastynum;
X
X	nastynum = sizeof(nasties);
X
X	for(i = rnd(u.ulevel/3); i > 0; --i) {
X
X		mtmp = mkmon_at(nasties[rn2(nastynum)], u.ux, u.uy);
X		mtmp->msleep = 0;
X		mtmp->mpeaceful = 0;
X	}
X#else
X	(void) makemon((struct permonst *)0, u.ux, u.uy);
X#endif
X	return(0);
X}
X
X#ifdef HARD
X/*	Here, we make trouble for the poor shmuck who actually	*/
X/*	managed to do in the Wizard.				*/
Xintervene() {
X
X	switch(rn2(6)) {
X
X	    case 0:
X	    case 1:	pline("You feel vaguely nervous.");
X			break;
X	    case 2:	pline("You notice a black glow surrounding you.");
X			rndcurse();
X			break;
X	    case 3:	aggravate();
X			break;
X	    case 4:	nasty();
X			break;
X	    case 5:	resurrect();
X			break;
X	}
X}
X
Xwizdead(mtmp)
Xregister struct monst	*mtmp;
X{
X	if(! u.udemigod)  {
X
X		u.udemigod = TRUE;
X		u.udg_cnt = rn1(250, 50);
X
X	/*  Make the wizard meaner the next time he appears  */
X		mtmp->data->mlevel++;
X		mtmp->data->ac--;
X	} else  
X		mtmp->data->mlevel++;
X}
X
X
X/*	Let's resurrect the wizard, for some unexpected fun.	*/
Xresurrect() {
Xregister struct monst	*mtmp;
X
X	    if(mtmp = makemon(PM_WIZARD, u.ux, u.uy)) {
X
X		mtmp->msleep = 1;
X		flags.no_of_wizards = 1;
X		pline("A voice booms out...");
X		pline("\"So you thought you could kill me, fool.\"");
X	    }
X
X}
X#endif /* HARD /**/
END_OF_wizard.c
if test 11381 -ne `wc -c <wizard.c`; then
    echo shar: \"wizard.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 10 \(of 16\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 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.")