[comp.sources.games] v03i012: NetHack2.2 - display oriented dungeons and dragons, Part12/20

games-request@tekred.TEK.COM (12/02/87)

Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 3, Issue 12
Archive-name: nethack2.2/Part12



#! /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 12 (of 20)."
# Contents:  pcmain.c pri.c unixmain.c version.c wizard.c
# Wrapped by billr@tekred on Tue Dec  1 16:25:05 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
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\" \(11972 characters\)
sed "s/^X//" >pcmain.c <<'END_OF_pcmain.c'
X/*	SCCS Id: @(#)pcmain.c	2.1	87/10/18
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* main.c - (PC) version */
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
X#ifdef GRAPHICS
X	/* Set the default values of the presentation characters */
X	memcpy((char *) &showsyms, (char *) &defsyms, sizeof(struct symbols));
X#endif
X#ifdef DGK
X	if ((dir = getenv("HACKDIR")) != (char *) NULL) {
X		(void) strcpy(hackdir, dir);
X		chdirx (dir, 1);
X	}
X	zero_finfo();
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				settty("Sorry, you can't operate in debug mode.\n");
X				clearlocks();
X				exit(0);
X			}
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	   (uptodate(fd) || !unlink(SAVEF))) {
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		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#ifdef HARD
X				if(!rn2(u.udemigod?25:(dlevel>30)?50:70))
X#else
X				if(!rn2(70))
X#endif
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 defined(KAA) && defined(BVH)
X			if(Polymorph && !rn2(100)) polyself();
X#endif
X			if(Searching && multi >= 0) (void) dosearch();
X			gethungry();
X			invault();
X			amulet();
X#ifdef HARD
X			if (!rn2(50+(u.ulevel*3))) u_wipe_engr(rnd(3));
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# ifdef REDO
X				else
X					pushch(ch);
X# endif
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 REDO
X		multi = 0;
X		pushch(0);		
X#endif
X	}
X}
X
X#ifdef DGK
Xstruct finfo	zfinfo = ZFINFO;
X
Xzero_finfo() {	/* zero "fileinfo" array to prevent crashes on level change */
X	int i;
X
X	for (i = 0 ; i <= MAXLEVEL; i++)
X		fileinfo[i] = zfinfo;
X}
X#endif
END_OF_pcmain.c
if test 11972 -ne `wc -c <pcmain.c`; then
    echo shar: \"pcmain.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pri.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pri.c\"
else
echo shar: Extracting \"pri.c\" \(12732 characters\)
sed "s/^X//" >pri.c <<'END_OF_pri.c'
X/*	SCCS Id: @(#)pri.c	2.1	87/11/09
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include <stdio.h>
X#include "hack.h"
X#ifdef GENIX
X#define	void	int	/* jhn - mod to prevent compiler from bombing */
X#endif
X#ifdef MSDOSCOLOR
Xextern int hilite();
X#endif
X
Xxchar scrlx, scrhx, scrly, scrhy;	/* corners of new area on screen */
X
Xextern char *hu_stat[];	/* in eat.c */
Xextern char *CD;
Xextern struct monst *makemon();
X
Xswallowed()
X{
X	char *ulook = "|@|";
X	ulook[1] = u.usym;
X
X	cls();
X	curs(u.ux-1, u.uy+1);
X	fputs("/-\\", stdout);
X	curx = u.ux+2;
X	curs(u.ux-1, u.uy+2);
X	fputs(ulook, stdout);
X	curx = u.ux+2;
X	curs(u.ux-1, u.uy+3);
X	fputs("\\-/", stdout);
X	curx = u.ux+2;
X	u.udispl = 1;
X	u.udisx = u.ux;
X	u.udisy = u.uy;
X}
X
Xsetclipped(){
X	error("Hack needs a screen of size at least %d by %d.\n",
X		ROWNO+2, COLNO);
X}
X
X#ifdef DGK
Xstatic int multipleAts;		/* TRUE if we have many at()'s to do */
Xstatic int DECgraphics;		/* The graphics mode toggle */
X
X#define DECgraphicsON() ((void) putchar('\16'), DECgraphics = TRUE)
X#define DECgraphicsOFF() ((void) putchar('\17'), DECgraphics = FALSE)
X#endif
X
Xat(x,y,ch)
Xregister xchar x,y;
Xchar ch;
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	y += 2;
X	curs(x,y);
X#ifdef DGK
X	if (flags.DECRainbow) {
X		/* If there are going to be many at()s in a row without
X		 * intervention, only change the graphics mode when the
X		 * character changes between graphic and regular.
X		 */
X		if (multipleAts) {
X			if (ch & 0x80) {
X				if (!DECgraphics)
X					DECgraphicsON();
X				(void) putchar(ch ^ 0x80); /* Strip 8th bit */
X			} else {
X				if (DECgraphics)
X					DECgraphicsOFF();
X				(void) putchar(ch);
X			}
X		/* Otherwise, we don't know how many at()s will be happening
X		 * before printing of normal strings, so change to graphics
X		 * mode when necessary, then change right back.
X		 */
X		} else {
X			if (ch & 0x80) {
X				DECgraphicsON();
X				(void) putchar(ch ^ 0x80); /* Strip 8th bit */
X				DECgraphicsOFF();
X			} else
X				(void) putchar(ch);
X		}
X	} else
X#endif
X#ifdef MSDOSCOLOR
X		hilite(ch);
X#else
X		(void) putchar(ch);
X#endif
X	curx++;
X}
X
Xprme(){
X	if(!Invisible) at(u.ux,u.uy,u.usym);
X}
X
Xdoredraw()
X{
X	docrt();
X	return(0);
X}
X
Xdocrt()
X{
X	register x,y;
X	register struct rm *room;
X	register struct monst *mtmp;
X
X	if(u.uswallow) {
X		swallowed();
X		return;
X	}
X	cls();
X
X/* Some ridiculous code to get display of @ and monsters (almost) right */
X	if(!Invisible) {
X		levl[(u.udisx = u.ux)][(u.udisy = u.uy)].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/* This nonsense should disappear soon --------------------------------- */
X
X#if defined(DGK) && !defined(MSDOSCOLOR)
X	/* I don't know DEC Rainbows, but if HILITE_COLOR is applicable,
X	 * the !defined(HILITE_COLOR) will have to be compensated for.
X	 * -kjs */
X	/* For DEC Rainbows, we must translate each character to strip
X	 * out the 8th bit if necessary.
X	 */
X	if (flags.DECRainbow) {
X		multipleAts = TRUE;
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);
X				} else if(room->seen)
X					at(x,y,room->scrsym);
X		multipleAts = FALSE;
X		if (DECgraphics)
X			DECgraphicsOFF();
X	} else {
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
X			memset(buf, ' ', COLNO);
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				fputs(buf + start, stdout);
X				curx = end + 1;
X			}
X		}
X	}
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);
X			} else if(room->seen)
X				at(x,y,room->scrsym);
X#endif
X	scrlx = COLNO;
X	scrly = ROWNO;
X	scrhx = scrhy = 0;
X	flags.botlx = 1;
X	bot();
X}
X
Xdocorner(xmin,ymax) register xmin,ymax; {
X	register x,y;
X	register struct rm *room;
X	register struct monst *mtmp;
X
X	if(u.uswallow) {	/* Can be done more efficiently */
X		swallowed();
X		return;
X	}
X
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 DGK
X	if (flags.DECRainbow)
X		multipleAts = TRUE;
X#endif
X	for(y = 0; y < ymax; y++) {
X		if(y > ROWNO && CD) break;
X		curs(xmin,y+2);
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);
X			} else
X				if(room->seen)
X					at(x,y,room->scrsym);
X		    }
X		}
X	}
X#ifdef DGK
X	if (flags.DECRainbow) {
X		multipleAts = FALSE;
X		if (DECgraphics)
X			DECgraphicsOFF();
X	}
X#endif
X	if(ymax > ROWNO) {
X		cornbot(xmin-1);
X		if(ymax > ROWNO+1 && CD) {
X			curs(1,ROWNO+3);
X			cl_eos();
X		}
X	}
X}
X
X/* Trolls now regenerate thanks to KAA */
X
Xseeobjs(){
Xregister struct obj *obj, *obj2;
X	for(obj = fobj; obj; obj = obj2) {
X	    obj2 = obj->nobj;
X	    if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) {
X
X		if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) {
X			delobj(obj);
X			if (cansee(obj->ox, obj->oy)) 
X				pline("The troll rises from the dead!");
X			(void) makemon(PM_TROLL,obj->ox, obj->oy);
X		} else if (obj->age + 250 < moves) delobj(obj);
X	    }
X	}
X
X	for(obj = invent; obj; obj = obj2) {
X	    obj2 = obj->nobj;
X	    if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE) {
X
X		if (obj->otyp == DEAD_TROLL && obj->age + 20 < moves) {
X		    if (obj == uwep)
X			pline("The dead troll writhes out of your grasp!");
X		    else
X			pline("You feel squirming in your backpack!");
X		    (void)makemon(PM_TROLL,u.ux,u.uy);
X		    useup(obj);
X		} else if (obj->age + 250 < moves) useup(obj);
X	    }
X	}
X}
X
Xseemons(){
Xregister struct monst *mtmp;
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
X		if(mtmp->data->mlet == ';')
X			mtmp->minvis = (u.ustuck != mtmp &&
X					levl[mtmp->mx][mtmp->my].typ == POOL);
X		pmon(mtmp);
X#ifndef NOWORM
X		if(mtmp->wormno) wormsee(mtmp->wormno);
X#endif
X	}
X}
X
Xpmon(mon) register struct monst *mon; {
Xregister int show = (Blind && Telepat) || canseemon(mon);
X	if(mon->mdispl){
X		if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
X			unpmon(mon);
X	}
X
X/* If you're hallucinating, the monster must be redrawn even if it has
X   already been printed.  Problem: the monster must also be redrawn right
X   after hallucination is over, so it looks normal again.  Therefore 
X   code similar to pmon is in timeout.c. */
X	if(show && (!mon->mdispl || Hallucination)) {
X		if (Hallucination) 
X		atl(mon->mx,mon->my,
X			(!mon->mimic || Protection_from_shape_changers) ?
X				rndmonsym() :
X				(mon->mappearance == DOOR_SYM) ? DOOR_SYM
X				: rndobjsym());
X		else
X
X		atl(mon->mx,mon->my,
X		 (!mon->mappearance
X		  || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHAN)].p_flgs
X		 ) ? mon->data->mlet : mon->mappearance);
X		mon->mdispl = 1;
X		mon->mdx = mon->mx;
X		mon->mdy = mon->my;
X	}
X}
X
Xunpmon(mon) register struct monst *mon; {
X	if(mon->mdispl){
X		newsym(mon->mdx, mon->mdy);
X		mon->mdispl = 0;
X	}
X}
X
Xnscr()
X{
X	register 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);
X			}
X	scrhx = scrhy = 0;
X	scrlx = COLNO;
X	scrly = ROWNO;
X}
X
X/* 100 suffices for bot(); no relation with COLNO */
Xchar oldbot[100], newbot[100];
Xcornbot(lth)
Xregister int lth;
X{
X	if(lth < sizeof(oldbot)) {
X		oldbot[lth] = 0;
X		flags.botl = 1;
X	}
X}
X
Xbot()
X{
Xregister char *ob = oldbot, *nb = newbot;
Xregister int i;
Xextern char *eos();
X	if(flags.botlx) *ob = 0;
X	flags.botl = flags.botlx = 0;
X	(void) sprintf(newbot,
X#ifdef GOLD_ON_BOTL
X# ifdef SPELLS
X		"Lev %-2d Gp %-5lu Hp %3d(%d) Ep %3d(%d) Ac %-2d  ",
X		dlevel, u.ugold,
X#  ifdef KAA
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		"Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  ",
X		dlevel, u.ugold,
X#  ifdef KAA
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#else
X# ifdef SPELLS
X		"Level %-2d Hp %3d(%d) Energy %3d(%d) Ac %-2d ",
X		dlevel,
X#  ifdef KAA
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		"Level %-2d   Hp %3d(%d)   Ac %-2d   ",
X		dlevel,
X#  ifdef KAA
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#endif
X#ifdef KAA
X	if (u.mtimedone)
X		(void) sprintf(eos(newbot), "HD %d", mons[u.umonnum].mlevel);
X	else
X#endif
X	    if(u.ustr>18) {
X		if(u.ustr>117)
X		    (void) strcat(newbot,"Str 18/**");
X		else
X		    (void) sprintf(eos(newbot), "Str 18/%02d",u.ustr-18);
X	    } else
X		(void) sprintf(eos(newbot), "Str %-2d   ",u.ustr);
X#ifdef EXP_ON_BOTL
X	(void) sprintf(eos(newbot), "  Exp %2d/%-5lu ", u.ulevel,u.uexp);
X#else
X	(void) sprintf(eos(newbot), "   Exp %2u  ", u.ulevel);
X#endif
X	(void) strcat(newbot, hu_stat[u.uhs]);
X	if(flags.time)
X	    (void) sprintf(eos(newbot), "  %ld", moves);
X	if(strlen(newbot) >= COLNO) {
X		register char *bp0, *bp1;
X		bp0 = bp1 = newbot;
X		do {
X			if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
X				*bp1++ = *bp0;
X		} while(*bp0++);
X	}
X	for(i = 1; i<COLNO; i++) {
X		if(*ob != *nb){
X			curs(i,ROWNO+2);
X			(void) putchar(*nb ? *nb : ' ');
X			curx++;
X		}
X		if(*ob) ob++;
X		if(*nb) nb++;
X	}
X	(void) strcpy(oldbot, newbot);
X}
X
X#if defined(WAN_PROBING) || defined(KAA)
Xmstatusline(mtmp) register struct monst *mtmp; {
X	pline("Status of %s: ", monnam(mtmp));
X	pline("Level %-2d  Gold %-5lu  Hp %3d(%d)",
X	    mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax);
X	pline("Ac %-2d  Dam %d %s %s",
X	    mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1),
X	    mtmp->mcan ? ", cancelled" : "" ,mtmp->mtame ? " (tame)" : "");
X}
X
Xextern char plname[];
Xustatusline() {
X	pline("Status of %s ", plname);
X	pline("Level %d, gold %lu, hit points %d(%d), AC %d.",
X# ifdef KAA
X		u.ulevel, 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#endif
X
Xcls(){
X	if(flags.toplin == 1)
X		more();
X	flags.toplin = 0;
X
X	clear_screen();
X
X	flags.botlx = 1;
X}
X
Xrndmonsym() {
X	register int x;
X	if((x=rn2(58)) < 26)
X		return('a'+x);
X	else if (x<52)
X		return('A'+x-26);
X	else switch(x) {
X		case 52: return(';');
X		case 53: return('&');
X		case 54: return(':');
X		case 55: return('\'');
X		case 56: return(',');
X		case 57: return('9');
X		default: impossible("Bad random monster %d",x); return('{');
X	}
X}
X
Xrndobjsym() {
X	char *rndsym=")[!?%/=*($`";
X	return *(rndsym+rn2(11));
X}
X
Xchar *hcolors[] = { "ultraviolet","infrared","hot pink", "psychedelic",
X"bluish-orange","reddish-green","dark white","light black","loud",
X"salty","sweet","sour","bitter","luminescent","striped","polka-dotted",
X"square","round","triangular","brilliant","navy blue","cerise",
X"chartreuse","copper","sea green","spiral","swirly","blotchy",
X"fluorescent green","burnt orange","indigo","amber","tan",
X"sky blue-pink","lemon yellow" };
X
Xchar *
Xhcolor() {
X	return hcolors[rn2(35)];
X}
X
X#ifdef MSDOSCOLOR
X/* what if a level character is the same as an object/monster? */
X
Xextern char obj_symbols[];
X
Xhilite(let)
Xchar let;
X{
X	char *isobjct = index(obj_symbols, let);
X	int ismnst();
X
X	if (!HI || !HE) {
X		(void) putchar(let);
X		return;
X	}
X	if (isobjct != NULL || let == GOLD_SYM) {
X	/* is an object */
X		printf("%s%c%s", HI_OBJ, let, HE);
X	} else if (ismnst(let)) {
X	/* is a monster */
X		printf("%s%c%s", HI_MON, let, HE);
X	} else {	
X	/* default */
X		(void) putchar(let);
X	}
X}
X
Xint
Xismnst(let)
Xchar let;
X{
X	register int ct;
X	register struct permonst *ptr;
X
X	for (ct = 0 ; ct < CMNUM + 2 ; ct++) {
X		ptr = &mons[ct];
X		if(ptr->mlet == let) return(1);
X	}
X	if (let == '1') return(1);
X	else if (let == '2') return(1);
X	else if (let == ';') return(1);
X	else return(0);
X}
X#endif
END_OF_pri.c
if test 12732 -ne `wc -c <pri.c`; then
    echo shar: \"pri.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f unixmain.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"unixmain.c\"
else
echo shar: Extracting \"unixmain.c\" \(12402 characters\)
sed "s/^X//" >unixmain.c <<'END_OF_unixmain.c'
X/*	SCCS Id: @(#)unixmain.c	2.1	87/10/18
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* main.c - (Unix) version */
X
X#include <stdio.h>
X#include <signal.h>
X#include "hack.h"
X
X#ifdef QUEST
X#define	gamename	"NetQuest"
X#else
X#define	gamename	"NetHack"
X#endif
X
Xextern char *getlogin(), *getenv();
Xextern char plname[PL_NSIZ], pl_character[PL_CSIZ];
X
Xint (*afternmv)();
Xint (*occupation)();
X
Xint done1();
Xint hangup();
X
Xint hackpid;				/* current pid */
Xint locknum;				/* max num of players */
X#ifdef DEF_PAGER
Xchar *catmore;				/* default pager */
X#endif
Xchar SAVEF[PL_NSIZ + 11] = "save/";	/* save/99999player */
Xchar *hname;		/* name of the game (argv[0] of call) */
Xchar obuf[BUFSIZ];	/* BUFSIZ is defined in stdio.h */
X
Xextern char *nomovemsg;
Xextern long wailmsg;
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	register int fd;
X#ifdef CHDIR
X	register char *dir;
X#endif
X
X	hname = argv[0];
X	hackpid = getpid();
X
X#ifdef CHDIR			/* otherwise no chdir() */
X	/*
X	 * See if we must change directory to the playground.
X	 * (Perhaps hack runs suid and playground is inaccessible
X	 *  for the player.)
X	 * The environment variable HACKDIR is overridden by a
X	 *  -d command line option (must be the first option given)
X	 */
X
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 /* CHDIR /**/
X#ifdef GRAPHICS
X	/* Set the default values of the presentation characters */
X	memcpy((char *) &showsyms, (char *) &defsyms, sizeof(struct symbols));
X#endif
X#ifdef HACKOPTIONS
X	initoptions();
X#endif
X	whoami();
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#ifdef CHDIR
X		chdirx(dir,0);
X#endif
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	(void) signal(SIGHUP, hangup);
X
X	/*
X	 * Find the creation date of this game,
X	 * so as to avoid restoring outdated savefiles.
X	 */
X	gethdate(hname);
X
X	/*
X	 * We cannot do chdir earlier, otherwise gethdate will fail.
X	 */
X#ifdef CHDIR
X	chdirx(dir,1);
X#endif
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			if(!strcmp(getlogin(), WIZARD))
X				wizard = TRUE;
X			else {
X				settty("Sorry, you can't operate in debug mode.\n");
X				clearlocks();
X				exit(0);
X			}
X			break;
X#endif
X#ifdef NEWS
X		case 'n':
X			flags.nonews = TRUE;
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		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	if(argc > 1)
X		locknum = atoi(argv[1]);
X#ifdef MAX_NR_OF_PLAYERS
X	if(!locknum || locknum > MAX_NR_OF_PLAYERS)
X		locknum = MAX_NR_OF_PLAYERS;
X#endif
X#ifdef DEF_PAGER
X	if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER")))
X		catmore = DEF_PAGER;
X#endif
X#ifdef MAIL
X	getmailstatus();
X#endif
X#ifdef WIZARD
X	if(wizard) (void) strcpy(plname, "wizard"); else
X#endif
X	if(!*plname || !strncmp(plname, "player", 4)
X		    || !strncmp(plname, "games", 4))
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#endif
X		/*
X		 * check for multiple games under the same name
X		 * (if !locknum) or check max nr of players (otherwise)
X		 */
X		(void) signal(SIGQUIT,SIG_IGN);
X		(void) signal(SIGINT,SIG_IGN);
X		if(!locknum)
X			(void) strcpy(lock,plname);
X		getlock();	/* sets lock if locknum != 0 */
X#ifdef WIZARD
X	} else {
X		register char *sfoo;
X		extern char genocided[], fut_geno[];
X		(void) strcpy(lock,plname);
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				extern struct permonst mons[CMNUM+2];
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	setftty();
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		(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, gamename);
X		flags.move = 0;
X	} else {
Xnot_recovered:
X		newgame();
X		/* give welcome message before pickup messages */
X		pline("Hello %s, welcome to %s!", plname, gamename);
X
X		pickup(1);
X		read_engr_at(u.ux,u.uy);
X		flags.move = 1;
X	}
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
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#ifdef HARD
X				if(!rn2(u.udemigod?25:(dlevel>30)?50:70))
X#else
X				if(!rn2(70))
X#endif
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			if(flags.time) flags.botl = 1;
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 defined(KAA) && defined(BVH)
X			if(Polymorph && !rn2(100)) polyself();
X#endif
X			if(Searching && multi >= 0) (void) dosearch();
X			gethungry();
X			invault();
X			amulet();
X#ifdef HARD
X			if (!rn2(50+(u.ulevel*3))) u_wipe_engr(rnd(3));
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
X			if (monster_nearby())
X				stop_occupation();
X			else if ((*occupation)() == 0)
X				occupation = 0;
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#ifdef MAIL
X			ckmailstatus();
X#endif
X			rhack((char *) 0);
X		}
X		if(multi && multi%7 == 0)
X			(void) fflush(stdout);
X	}
X}
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
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		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
Xstatic
Xchdirx(dir, wr)
Xchar *dir;
Xboolean wr;
X{
X
X# ifdef SECURE
X	if(dir					/* User specified directory? */
X#  ifdef HACKDIR
X	       && strcmp(dir, HACKDIR)		/* and not the default? */
X#  endif
X		) {
X		(void) setuid(getuid());		/* Ron Wessels */
X		(void) setgid(getgid());
X	}
X# endif
X
X# ifdef HACKDIR
X	if(dir == NULL)
X		dir = HACKDIR;
X# endif
X
X	if(dir && chdir(dir) < 0) {
X		perror(dir);
X		error("Cannot chdir to %s.", dir);
X	}
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		printf("Warning: cannot write %s/%s", dir, RECORD);
X		getret();
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 REDO
X		multi = 0;
X		pushch(0);		
X#endif
X	}
X}
X
Xwhoami() {
X	/*
X	 * Who am i? Algorithm: 1. Use name as specified in HACKOPTIONS
X	 *			2. Use $USER or $LOGNAME	(if 1. fails)
X	 *			3. Use getlogin()		(if 2. fails)
X	 * The resulting name is overridden by command line options.
X	 * If everything fails, or if the resulting name is some generic
X	 * account like "games", "play", "player", "hack" then eventually
X	 * we'll ask him.
X	 * Note that we trust him here; it is possible to play under
X	 * somebody else's name.
X	 */
X	register char *s;
X
X#ifndef DGKMOD
X	initoptions();
X#endif
X	if(!*plname && (s = getenv("USER")))
X		(void) strncpy(plname, s, sizeof(plname)-1);
X	if(!*plname && (s = getenv("LOGNAME")))
X		(void) strncpy(plname, s, sizeof(plname)-1);
X	if(!*plname && (s = getlogin()))
X		(void) strncpy(plname, s, sizeof(plname)-1);
X}
X
Xnewgame() {
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	{
X		register struct monst *mtmp;
X
X		/* Move the monster from under you or else
X		 * makedog() will fail when it calls makemon().
X		 * 			- ucsfcgl!kneller
X		 */
X		if (mtmp = m_at(u.ux, u.uy))  mnexto(mtmp);
X	}
X	(void) makedog();
X	seemons();
X#ifdef NEWS
X	if(flags.nonews || !readnews())
X		/* after reading news we did docrt() already */
X#endif
X		docrt();
X	return(0);
X}
X
X#ifdef GENIX
Xjhndist(x1,y1,x2,y2)
X{
X	int x,y;
X	x=x1-x2;
X	y=y1-y2;
X	return (x*x + y*y);
X}
X#endif
END_OF_unixmain.c
if test 12402 -ne `wc -c <unixmain.c`; then
    echo shar: \"unixmain.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f version.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"version.c\"
else
echo shar: Extracting \"version.c\" \(1830 characters\)
sed "s/^X//" >version.c <<'END_OF_version.c'
X/*	SCCS Id: @(#)version.c	2.1	87/11/09
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include	"hack.h"
X#include	"date.h"
X
Xdoversion(){
X
X#ifdef BETA
X	pline("%s Net%s Beta Version %s - last build %s.",
X#else
X	pline("%s Net%s Version %s - last build %s.",
X#endif
X#ifdef UNIX
X		"Unix"
X#endif
X#ifdef MSDOS
X		"PC"
X#endif
X#ifdef QUEST
X		, "Quest"
X#else
X		, "Hack"
X#endif
X		, VERSION, datestring);
X	return(0);
X}
X
X#ifdef DGKMOD
X
X#define pg_line(x)	if(page_line(x)) goto quit;
X
XdoMSCversion()
X{
X	char	buf[BUFSZ];
X
X	set_pager(0);
X	sprintf(buf, "Behold mortal, the origins of %s Net%s...",
X#ifdef UNIX
X		"Unix"
X#endif
X#ifdef MSDOS
X		"PC"
X#endif
X#ifdef QUEST
X		, "Quest");
X#else
X		, "Hack");
X#endif
X	pg_line("");
X	pg_line(buf); pg_line(""); pg_line("");
X
X	pg_line("The original HACK was written by Jay Fenlason with help from");
X	pg_line("Kenny Woodland, Mike Thome and Jon Payne.");
X
X	pg_line("");
X	pg_line("Andries Brouwer did a major re-write and published (at least)");
X	pg_line("two versions (1.0.2 and 1.0.3) to the Usenet.");
X
X	pg_line("");
X	pg_line("PC HACK 3.51K was an MSDOS(tm) version of HACK 1.03.");
X	pg_line("The PC implementation was done in Microsoft(tm) C by Don Kneller");
X	pg_line("and modified by Ken Arromdee.");
X
X	pg_line("");
X	pg_line("PC and UNIX HACK were merged by Mike Stephenson and Ken Arromdee");
X	pg_line("incorporating many modifications and features made by the above,");
X	pg_line("as well as the following honored hackers:");
X
X	pg_line("");
X	pg_line("    Scott R. Turner    Tom Almy           John S. Bien");
X	pg_line("    Gil Neiger         Ralf Brown         Eric S. Raymond");
X	pg_line("    Eric Backus        Roland McGrath     Greg Laskin");
X	pg_line("    Bruce Holloway     Richard P. Hughey  Kevin Sweet");
X	set_pager(1);
X	return(0);
Xquit:
X	set_pager(2);
X	return(0);
X}
X
X#endif
END_OF_version.c
if test 1830 -ne `wc -c <version.c`; then
    echo shar: \"version.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\" \(11805 characters\)
sed "s/^X//" >wizard.c <<'END_OF_wizard.c'
X/*	SCCS Id: @(#)wizard.c	2.2	87/11/29
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
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();
Xextern struct obj *carrying();
X
X#if defined(HARD) || defined(DGKMOD)
X# ifdef SAC
Xchar	nasties[] = "cdDeImoPTUVwxXz3&,:;";
X# else
Xchar	nasties[] = "cdDeImoPTUVwxXz&,:;";
X# endif
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_SYM)) {
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 /* KAA /**/
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			    /* blindfold keeps pie filling out of your eyes */
X			    if (!Blindfolded) {
X				u.ucreamed += (blindinc = rnd(25));
X				Blinded += blindinc;
X				seeoff(0);
X			    }
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#ifndef RPH
X	if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return(1);
X#endif
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(10)
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#ifdef HARD
X			nasty();
X#endif
X			aggravate();	/* aggravate all the monsters */
X			/* fall into next case */
X		    case 2:
X			if (flags.no_of_wizards == 1 && !rn2(3)) {
X			    /* if only 1 wizard, clone himself */
X			    pline("Double Trouble...");
X			    clonewiz(mtmp);
X			}
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, u.ux, u.uy)) {
X		flags.no_of_wizards = 2;
X		mtmp2->mtame = mtmp2->mpeaceful = 0;
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, tmp;
X
X	nastynum = sizeof(nasties) - 1;
X	tmp = (u.ulevel > 3) ? u.ulevel/3 : 1;	/* just in case -- rph */
X
X	for(i = rnd(tmp); i > 0; --i)
X	    if((mtmp = mkmon_at(nasties[rn2(nastynum)], u.ux, u.uy)))  {
X
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	flags.no_of_wizards--;
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 = mtmp->mtame = mtmp->mpeaceful = 0;
X		flags.no_of_wizards++;
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 11805 -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 12 \(of 20\).
cp /dev/null ark12isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 20 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