[net.sources.games] Hack 1.0.2 - part 7 of 10

aeb@mcvax.UUCP (Andries Brouwer) (04/10/85)

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# hack.pri.c hack.read.c hack.rip.c hack.rumors.c hack.save.c hack.search.c
# hack.shknam.c hack.steal.c

echo x - hack.pri.c
cat > "hack.pri.c" << '//E*O*F hack.pri.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.pri.c - version 1.0.2 */

#include "hack.h"
#include <stdio.h>
xchar scrlx, scrhx, scrly, scrhy;	/* corners of new area on screen */

extern char *hu_stat[];	/* in eat.c */
extern char *CD;

swallowed()
{
	char *ulook = "|@|";
	ulook[1] = u.usym;

	cls();
	curs(u.ux-1, u.uy+1);
	fputs("/-\\", stdout);
	curx = u.ux+2;
	curs(u.ux-1, u.uy+2);
	fputs(ulook, stdout);
	curx = u.ux+2;
	curs(u.ux-1, u.uy+3);
	fputs("\\-/", stdout);
	curx = u.ux+2;
	u.udispl = 1;
	u.udisx = u.ux;
	u.udisy = u.uy;
}


/*VARARGS1*/
boolean panicking;

panic(str,a1,a2,a3,a4,a5,a6)
char *str;
{
	if(panicking++) exit(1);    /* avoid loops - this should never happen*/
	home();
	puts(" Suddenly, the dungeon collapses.");
	fputs(" ERROR:  ", stdout);
	printf(str,a1,a2,a3,a4,a5,a6);
#ifdef DEBUG
#ifdef UNIX
	if(!fork())
		abort();	/* generate core dump */
#endif UNIX
#endif DEBUG
	more();			/* contains a fflush() */
	done("panicked");
}

atl(x,y,ch)
register x,y;
{
	register struct rm *crm = &levl[x][y];

	if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){
		impossible("atl(%d,%d,%c)",x,y,ch);
		return;
	}
	if(crm->seen && crm->scrsym == ch) return;
	crm->scrsym = ch;
	crm->new = 1;
	on_scr(x,y);
}

on_scr(x,y)
register x,y;
{
	if(x < scrlx) scrlx = x;
	if(x > scrhx) scrhx = x;
	if(y < scrly) scrly = y;
	if(y > scrhy) scrhy = y;
}

/* call: (x,y) - display
	(-1,0) - close (leave last symbol)
	(-1,-1)- close (undo last symbol)
	(-1,let)-open: initialize symbol
	(-2,let)-change let
*/

tmp_at(x,y) schar x,y; {
static schar prevx, prevy;
static char let;
	if((int)x == -2){	/* change let call */
		let = y;
		return;
	}
	if((int)x == -1 && (int)y >= 0){	/* open or close call */
		let = y;
		prevx = -1;
		return;
	}
	if(prevx >= 0 && cansee(prevx,prevy)) {
		delay_output();
		prl(prevx, prevy);	/* in case there was a monster */
		at(prevx, prevy, levl[prevx][prevy].scrsym);
	}
	if(x >= 0){	/* normal call */
		if(cansee(x,y)) at(x,y,let);
		prevx = x;
		prevy = y;
	} else {	/* close call */
		let = 0;
		prevx = -1;
	}
}

/* like the previous, but the symbols are first erased on completion */
Tmp_at(x,y) schar x,y; {
static char let;
static xchar cnt;
static coord tc[COLNO];		/* but watch reflecting beams! */
register xx,yy;
	if((int)x == -1) {
		if(y > 0) {	/* open call */
			let = y;
			cnt = 0;
			return;
		}
		/* close call (do not distinguish y==0 and y==-1) */
		while(cnt--) {
			xx = tc[cnt].x;
			yy = tc[cnt].y;
			prl(xx, yy);
			at(xx, yy, levl[xx][yy].scrsym);
		}
		cnt = let = 0;	/* superfluous */
		return;
	}
	if((int)x == -2) {	/* change let call */
		let = y;
		return;
	}
	/* normal call */
	if(cansee(x,y)) {
		if(cnt) delay_output();
		at(x,y,let);
		tc[cnt].x = x;
		tc[cnt].y = y;
		if(++cnt >= COLNO) panic("Tmp_at overflow?");
		levl[x][y].new = 0;	/* prevent pline-nscr erasing --- */
	}
}

setclipped(){
	error("Hack needs a screen of size at least %d by %d.\n",
		ROWNO+2, COLNO);
}

at(x,y,ch)
register xchar x,y;
char ch;
{
#ifndef lint
	/* if xchar is unsigned, lint will complain about  if(x < 0)  */
	if(x < 0 || x > COLNO-1 || y < 0 || y > ROWNO-1) {
		impossible("At gets 0%o at %d %d.", ch, x, y);
		return;
	}
#endif lint
	if(!ch) {
		impossible("At gets null at %d %d.", x, y);
		return;
	}
	y += 2;
	curs(x,y);
	(void) putchar(ch);
	curx++;
}

prme(){
	if(!Invis) at(u.ux,u.uy,u.usym);
}

doredraw()
{
	docrt();
	return(0);
}

docrt()
{
	register x,y;
	register struct rm *room;

	if(u.uswallow) {
		swallowed();
		return;
	}
	cls();
	if(!Invis){
		levl[(u.udisx = u.ux)][(u.udisy = u.uy)].scrsym = u.usym;
		levl[u.udisx][u.udisy].seen = 1;
		u.udispl = 1;
	} else	u.udispl = 0;

#ifdef RIDICULOUS_CODE
	/* %% - is this really necessary? - it causes bugs when Blind */
	/* declare mtmp */
	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
		if(mtmp->mdispl && !(room = &levl[mtmp->mx][mtmp->my])->new &&
		   !room->seen)
			mtmp->mdispl = 0;
#endif RIDICULOUS_CODE

	for(y = 0; y < ROWNO; y++)
		for(x = 0; x < COLNO; x++)
			if((room = &levl[x][y])->new) {
				room->new = 0;
				at(x,y,room->scrsym);
			} else if(room->seen)
				at(x,y,room->scrsym);
	scrlx = COLNO;
	scrly = ROWNO;
	scrhx = scrhy = 0;
	flags.botlx = 1;
	bot();
}

docorner(xmin,ymax) register xmin,ymax; {
	register x,y;
	register struct rm *room;
	if(u.uswallow) {	/* Can be done more efficiently */
		swallowed();
		return;
	}
	for(y = 0; y < ymax; y++) {
		if(y > ROWNO && CD) break;
		curs(xmin,y+2);
		cl_end();
		if(y < ROWNO) {
		    for(x = xmin; x < COLNO; x++) {
			if((room = &levl[x][y])->new) {
				room->new = 0;
				at(x,y,room->scrsym);
			} else
				if(room->seen)
					at(x,y,room->scrsym);
		    }
		}
	}
	if(ymax > ROWNO) {
		cornbot(xmin-1);
		if(ymax > ROWNO+1 && CD) {
			curs(1,ROWNO+3);
			cl_eos();
		}
	}
}

curs_on_u(){
	curs(u.ux, u.uy+2);
}

pru()
{
	if(u.udispl && (Invis || u.udisx != u.ux || u.udisy != u.uy))
		/* if(! levl[u.udisx][u.udisy].new) */
			if(!vism_at(u.udisx, u.udisy))
				newsym(u.udisx, u.udisy);
	if(Invis) {
		u.udispl = 0;
		prl(u.ux,u.uy);
	} else
	if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
		atl(u.ux, u.uy, u.usym);
		u.udispl = 1;
		u.udisx = u.ux;
		u.udisy = u.uy;
	}
	levl[u.ux][u.uy].seen = 1;
}

#ifndef NOWORM
#include	"def.wseg.h"
extern struct wseg *m_atseg;
#endif NOWORM

/* print a position that is visible for @ */
prl(x,y)
{
	register struct rm *room;
	register struct monst *mtmp;
	register struct obj *otmp;

	if(x == u.ux && y == u.uy && !Invis) {
		pru();
		return;
	}
	if(!isok(x,y)) return;
	room = &levl[x][y];
	if((!room->typ) ||
	   (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR))
		return;
	if((mtmp = m_at(x,y)) && !mtmp->mhide &&
		(!mtmp->minvis || See_invisible)) {
#ifndef NOWORM
		if(m_atseg)
			pwseg(m_atseg);
		else
#endif NOWORM
		pmon(mtmp);
	}
	else if((otmp = o_at(x,y)) && room->typ != POOL)
		atl(x,y,otmp->olet);
	else if(mtmp && (!mtmp->minvis || See_invisible)) {
		/* must be a hiding monster, but not hiding right now */
		/* assume for the moment that long worms do not hide */
		pmon(mtmp);
	}
	else if(g_at(x,y) && room->typ != POOL)
		atl(x,y,'$');
	else if(!room->seen || room->scrsym == ' ') {
		room->new = room->seen = 1;
		newsym(x,y);
		on_scr(x,y);
	}
	room->seen = 1;
}

char
news0(x,y)
register xchar x,y;
{
	register struct obj *otmp;
	register struct trap *ttmp;
	struct rm *room;
	register char tmp;

	room = &levl[x][y];
	if(!room->seen) tmp = ' ';
	else if(room->typ == POOL) tmp = POOL_SYM;
	else if(!Blind && (otmp = o_at(x,y))) tmp = otmp->olet;
	else if(!Blind && g_at(x,y)) tmp = '$';
	else if(x == xupstair && y == yupstair) tmp = '<';
	else if(x == xdnstair && y == ydnstair) tmp = '>';
	else if((ttmp = t_at(x,y)) && ttmp->tseen) tmp = '^';
	else switch(room->typ) {
	case SCORR:
	case SDOOR:
		tmp = room->scrsym;	/* %% wrong after killing mimic ! */
		break;
	case HWALL:
		tmp = '-';
		break;
	case VWALL:
		tmp = '|';
		break;
	case LDOOR:
	case DOOR:
		tmp = '+';
		break;
	case CORR:
		tmp = CORR_SYM;
		break;
	case ROOM:
		if(room->lit || cansee(x,y) || Blind) tmp = '.';
		else tmp = ' ';
		break;
/*
	case POOL:
		tmp = POOL_SYM;
		break;
*/
	default:
		tmp = ERRCHAR;
	}
	return(tmp);
}

newsym(x,y)
register x,y;
{
	atl(x,y,news0(x,y));
}

/* used with wand of digging (or pick-axe): fill scrsym and force display */
/* also when a POOL evaporates */
mnewsym(x,y)
register x,y;
{
	register struct monst *mtmp = m_at(x,y);
	register struct rm *room;
	char newscrsym;

	if(x == u.ux && y == u.uy && !Invis)
		return;
	if(!mtmp || (mtmp->minvis && !See_invisible) ||
		    (mtmp->mhide && o_at(x,y))){
		room = &levl[x][y];
		newscrsym = news0(x,y);
		if(room->scrsym != newscrsym) {
			room->scrsym = newscrsym;
			room->seen = 0;
		}
	}
}

nosee(x,y)
register x,y;
{
	register struct rm *room;

	if(!isok(x,y)) return;
	room = &levl[x][y];
	if(room->scrsym == '.' && !room->lit && !Blind) {
		room->scrsym = ' ';
		room->new = 1;
		on_scr(x,y);
	}
}

#ifndef QUEST
prl1(x,y)
register x,y;
{
	if(u.dx) {
		if(u.dy) {
			prl(x-(2*u.dx),y);
			prl(x-u.dx,y);
			prl(x,y);
			prl(x,y-u.dy);
			prl(x,y-(2*u.dy));
		} else {
			prl(x,y-1);
			prl(x,y);
			prl(x,y+1);
		}
	} else {
		prl(x-1,y);
		prl(x,y);
		prl(x+1,y);
	}
}

nose1(x,y)
register x,y;
{
	if(u.dx) {
		if(u.dy) {
			nosee(x,u.uy);
			nosee(x,u.uy-u.dy);
			nosee(x,y);
			nosee(u.ux-u.dx,y);
			nosee(u.ux,y);
		} else {
			nosee(x,y-1);
			nosee(x,y);
			nosee(x,y+1);
		}
	} else {
		nosee(x-1,y);
		nosee(x,y);
		nosee(x+1,y);
	}
}
#endif QUEST

vism_at(x,y) register x,y; {
register struct monst *mtmp;
register int csi = (See_invisible != 0);
	return((x == u.ux && y == u.uy && (!Invis || csi)) ? 1 :
		((mtmp = m_at(x,y)) && (!mtmp->minvis || csi) &&
			(!mtmp->mhide || !o_at(mtmp->mx,mtmp->my)))
		? cansee(x,y) : 0);
}

#ifdef NEWSCR
pobj(obj) register struct obj *obj; {
register int show = (!obj->oinvis || See_invisible) &&
		cansee(obj->ox,obj->oy);
	if(obj->odispl){
		if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
		if(!vism_at(obj->odx,obj->ody)){
			newsym(obj->odx, obj->ody);
			obj->odispl = 0;
		}
	}
	if(show && !vism_at(obj->ox,obj->oy)){
		atl(obj->ox,obj->oy,obj->olet);
		obj->odispl = 1;
		obj->odx = obj->ox;
		obj->ody = obj->oy;
	}
}
#endif NEWSCR

unpobj(obj) register struct obj *obj; {
/* 	if(obj->odispl){
		if(!vism_at(obj->odx, obj->ody))
			newsym(obj->odx, obj->ody);
		obj->odispl = 0;
	}
*/
	if(!vism_at(obj->ox,obj->oy))
		newsym(obj->ox,obj->oy);
}

seeobjs(){
register struct obj *obj, *obj2;
	for(obj = fobj; obj; obj = obj2) {
		obj2 = obj->nobj;
		if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
			&& obj->age + 250 < moves)
				delobj(obj);
	}
	for(obj = invent; obj; obj = obj2) {
		obj2 = obj->nobj;
		if(obj->olet == FOOD_SYM && obj->otyp >= CORPSE
			&& obj->age + 250 < moves)
				useup(obj);
	}
}

seemons(){
register struct monst *mtmp;
	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
		if(mtmp->data->mlet == ';')
			mtmp->minvis = (u.ustuck != mtmp &&
					levl[mtmp->mx][mtmp->my].typ == POOL);
		pmon(mtmp);
#ifndef NOWORM
		if(mtmp->wormno) wormsee(mtmp->wormno);
#endif NOWORM
	}
}

pmon(mon) register struct monst *mon; {
register int show = (Blind && Telepat) || canseemon(mon);
	if(mon->mdispl){
		if(mon->mdx != mon->mx || mon->mdy != mon->my || !show)
			unpmon(mon);
	}
	if(show && !mon->mdispl){
		atl(mon->mx,mon->my,
		 (!mon->mappearance
		  || u.uprops[PROP(RIN_PROTECTION_FROM_SHAPE_CHANGERS)].p_flgs
		 ) ? mon->data->mlet : mon->mappearance);
		mon->mdispl = 1;
		mon->mdx = mon->mx;
		mon->mdy = mon->my;
	}
}

unpmon(mon) register struct monst *mon; {
	if(mon->mdispl){
		newsym(mon->mdx, mon->mdy);
		mon->mdispl = 0;
	}
}

nscr()
{
	register x,y;
	register struct rm *room;

	if(u.uswallow || u.ux == FAR || flags.nscrinh) return;
	pru();
	for(y = scrly; y <= scrhy; y++)
		for(x = scrlx; x <= scrhx; x++)
			if((room = &levl[x][y])->new) {
				room->new = 0;
				at(x,y,room->scrsym);
			}
	scrhx = scrhy = 0;
	scrlx = COLNO;
	scrly = ROWNO;
}

/* 100 suffices for bot(); no relation with COLNO */
char oldbot[100], newbot[100];
cornbot(lth)
register int lth;
{
	if(lth < sizeof(oldbot)) {
		oldbot[lth] = 0;
		flags.botl = 1;
	}
}

bot()
{
register char *ob = oldbot, *nb = newbot;
register int i;
extern char *eos();
	if(flags.botlx) *ob = 0;
	flags.botl = flags.botlx = 0;
#ifdef GOLD_ON_BOTL
	(void) sprintf(newbot,
		"Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Str ",
		dlevel, u.ugold, u.uhp, u.uhpmax, u.uac);
#else
	(void) sprintf(newbot,
		"Level %-2d   Hp %3d(%d)   Ac %-2d   Str ",
		dlevel,  u.uhp, u.uhpmax, u.uac);
#endif GOLD_ON_BOTL
	if(u.ustr>18) {
	    if(u.ustr>117)
		(void) strcat(newbot,"18/**");
	    else
		(void) sprintf(eos(newbot), "18/%02d",u.ustr-18);
	} else
	    (void) sprintf(eos(newbot), "%-2d   ",u.ustr);
#ifdef EXP_ON_BOTL
	(void) sprintf(eos(newbot), "  Exp %2d/%-5lu ", u.ulevel,u.uexp);
#else
	(void) sprintf(eos(newbot), "   Exp %2u  ", u.ulevel);
#endif EXP_ON_BOTL
	(void) strcat(newbot, hu_stat[u.uhs]);
	if(flags.time)
	    (void) sprintf(eos(newbot), "  %ld", moves);
	if(strlen(newbot) >= COLNO) {
		register char *bp0, *bp1;
		bp0 = bp1 = newbot;
		do {
			if(*bp0 != ' ' || bp0[1] != ' ' || bp0[2] != ' ')
				*bp1++ = *bp0;
		} while(*bp0++);
	}
	for(i = 1; i<COLNO; i++) {
		if(*ob != *nb){
			curs(i,ROWNO+2);
			(void) putchar(*nb ? *nb : ' ');
			curx++;
		}
		if(*ob) ob++;
		if(*nb) nb++;
	}
	(void) strcpy(oldbot, newbot);
}

#ifdef WAN_PROBING
mstatusline(mtmp) register struct monst *mtmp; {
	pline("Status of %s: ", monnam(mtmp));
	pline("Level %-2d  Gold %-5lu  Hp %3d(%d)  Ac %-2d  Dam %d",
	    mtmp->data->mlevel, mtmp->mgold, mtmp->mhp, mtmp->mhpmax,
	    mtmp->data->ac, (mtmp->data->damn + 1) * (mtmp->data->damd + 1));
}
#endif WAN_PROBING

cls(){
	if(flags.toplin == 1)
		more();
	flags.toplin = 0;

	clear_screen();

	flags.botlx = 1;
}
//E*O*F hack.pri.c//

echo x - hack.read.c
cat > "hack.read.c" << '//E*O*F hack.read.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.read.c - version 1.0.2 */

#include "hack.h"

extern struct monst *makemon();
extern struct obj *mkobj_at();
int identify();

doread() {
	register struct obj *scroll;
	register boolean confused = (Confusion != 0);
	register boolean known = FALSE;

	scroll = getobj("?", "read");
	if(!scroll) return(0);
	if(!scroll->dknown && Blind) {
	    pline("Being blind, you cannot read the formula on the scroll.");
	    return(0);
	}
	if(Blind)
	  pline("As you pronounce the formula on it, the scroll disappears.");
	else
	  pline("As you read the scroll, it disappears.");
	if(confused)
	  pline("Being confused, you mispronounce the magic words ... ");

	switch(scroll->otyp) {
#ifdef MAIL
	case SCR_MAIL:
		readmail(/* scroll */);
		break;
#endif MAIL
	case SCR_ENCHANT_ARMOR:
	    {	extern struct obj *some_armor();
		register struct obj *otmp = some_armor();
		if(!otmp) {
			strange_feeling(scroll,"Your skin glows then fades.");
			return(1);
		}
		if(confused) {
			pline("Your %s glows silver for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 1;
			break;
		}
		if(otmp->spe > 3 && rn2(otmp->spe)) {
	pline("Your %s glows violently green for a while, then evaporates.",
			objects[otmp->otyp].oc_name);
			useup(otmp);
			break;
		}
		pline("Your %s glows green for a moment.",
			objects[otmp->otyp].oc_name);
		otmp->cursed = 0;
		otmp->spe++;
		break;
	    }
	case SCR_DESTROY_ARMOR:
		if(confused) {
			register struct obj *otmp = some_armor();
			if(!otmp) {
				strange_feeling(scroll,"Your bones itch.");
				return(1);
			}
			pline("Your %s glows purple for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 0;
			break;
		}
		if(uarm) {
		    pline("Your armor turns to dust and falls to the floor!");
		    useup(uarm);
		} else if(uarmh) {
		    pline("Your helmet turns to dust and is blown away!");
		    useup(uarmh);
		} else if(uarmg) {
			pline("Your gloves vanish!");
			useup(uarmg);
			selftouch("You");
		} else {
			strange_feeling(scroll,"Your skin itches.");
			return(1);
		}
		break;
	case SCR_CONFUSE_MONSTER:
		if(confused) {
			pline("Your hands begin to glow purple.");
			Confusion += rnd(100);
		} else {
			pline("Your hands begin to glow blue.");
			u.umconf = 1;
		}
		break;
	case SCR_SCARE_MONSTER:
	    {	register int ct = 0;
		register struct monst *mtmp;

		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
			if(cansee(mtmp->mx,mtmp->my)) {
				if(confused)
					mtmp->mflee = mtmp->mfroz =
					mtmp->msleep = 0;
				else
					mtmp->mflee = 1;
				ct++;
			}
		if(!ct) {
		    if(confused)
			pline("You hear sad wailing in the distance.");
		    else
			pline("You hear maniacal laughter in the distance.");
		}
		break;
	    }
	case SCR_BLANK_PAPER:
		if(confused)
		    pline("You see strange patterns on this scroll.");
		else
		    pline("This scroll seems to be blank.");
		break;
	case SCR_REMOVE_CURSE:
	    {	register struct obj *obj;
		if(confused)
		  pline("You feel like you need some help.");
		else
		  pline("You feel like someone is helping you.");
		for(obj = invent; obj ; obj = obj->nobj)
			if(obj->owornmask)
				obj->cursed = confused;
		if(Punished && !confused) {
			Punished = 0;
			freeobj(uchain);
			unpobj(uchain);
			free((char *) uchain);
			uball->spe = 0;
			uball->owornmask &= ~W_BALL;
			uchain = uball = (struct obj *) 0;
		}
		break;
	    }
	case SCR_CREATE_MONSTER:
	    {	register int cnt = 1;

		if(!rn2(73)) cnt += rnd(4);
		if(confused) cnt += 12;
		while(cnt--)
		    (void) makemon(confused ? PM_ACID_BLOB :
			(struct permonst *) 0, u.ux, u.uy);
		break;
	    }
	case SCR_ENCHANT_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows silver for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 1;
		} else
			if(!chwepon(scroll, 1))		/* tests for !uwep */
				return(1);
		break;
	case SCR_DAMAGE_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows purple for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 0;
		} else
			if(!chwepon(scroll, -1))	/* tests for !uwep */
				return(1);
		break;
	case SCR_TAMING:
	    {	register int i,j;
		register int bd = confused ? 5 : 1;
		register struct monst *mtmp;

		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
		if(mtmp = m_at(u.ux+i, u.uy+j))
			(void) tamedog(mtmp, (struct obj *) 0);
		break;
	    }
	case SCR_GENOCIDE:
	    {	extern char genocided[], fut_geno[];
		char buf[BUFSZ];
		register struct monst *mtmp, *mtmp2;

		pline("You have found a scroll of genocide!");
		known = TRUE;
		if(confused)
			*buf = u.usym;
		else do {
	    pline("What monster do you want to genocide (Type the letter)? ");
			getlin(buf);
		} while(strlen(buf) != 1 || !letter(*buf));
		if(!index(fut_geno, *buf))
			charcat(fut_geno, *buf);
		if(!index(genocided, *buf))
			charcat(genocided, *buf);
		else {
			pline("Such monsters do not exist in this world.");
			break;
		}
		for(mtmp = fmon; mtmp; mtmp = mtmp2){
			mtmp2 = mtmp->nmon;
			if(mtmp->data->mlet == *buf)
				mondead(mtmp);
		}
		pline("Wiped out all %c's.", *buf);
		if(*buf == u.usym) {
			killer = "scroll of genocide";
			u.uhp = -1;
		}
		break;
		}
	case SCR_LIGHT:
		if(!Blind) known = TRUE;
		litroom(!confused);
		break;
	case SCR_TELEPORTATION:
		if(confused)
			level_tele();
		else {
#ifdef QUEST
			register int oux = u.ux, ouy = u.uy;
			tele();
			if(dist(oux, ouy) > 100) known = TRUE;
#else QUEST
			register int uroom = inroom(u.ux, u.uy);
			tele();
			if(uroom != inroom(u.ux, u.uy)) known = TRUE;
#endif QUEST
		}
		break;
	case SCR_GOLD_DETECTION:
	    /* Unfortunately this code has become slightly less elegant,
	       now that gold and traps no longer are of the same type. */
	    if(confused) {
		register struct trap *ttmp;

		if(!ftrap) {
			strange_feeling(scroll, "Your toes stop itching.");
			return(1);
		} else {
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				if(ttmp->tx != u.ux || ttmp->ty != u.uy)
					goto outtrapmap;
			/* only under me - no separate display required */
			pline("Your toes itch!");
			break;
		outtrapmap:
			cls();
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				at(ttmp->tx, ttmp->ty, '$');
			prme();
			pline("You feel very greedy!");
		}
	    } else {
		register struct gold *gtmp;

		if(!fgold) {
			strange_feeling(scroll, "You feel materially poor.");
			return(1);
		} else {
			known = TRUE;
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				if(gtmp->gx != u.ux || gtmp->gy != u.uy)
					goto outgoldmap;
			/* only under me - no separate display required */
			pline("You notice some gold between your feet.");
			break;
		outgoldmap:
			cls();
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				at(gtmp->gx, gtmp->gy, '$');
			prme();
			pline("You feel very greedy, and sense gold!");
		}
	    }
		/* common sequel */
		more();
		docrt();
		break;
	case SCR_FOOD_DETECTION:
	    {	register ct = 0, ctu = 0;
		register struct obj *obj;
		register char foodsym = confused ? POTION_SYM : FOOD_SYM;

		for(obj = fobj; obj; obj = obj->nobj)
			if(obj->olet == FOOD_SYM) {
				if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
				else ct++;
			}
		if(!ct && !ctu) {
			strange_feeling(scroll,"Your nose twitches.");
			return(1);
		} else if(!ct) {
			known = TRUE;
			pline("You smell %s close nearby.",
				confused ? "something" : "food");
			
		} else {
			known = TRUE;
			cls();
			for(obj = fobj; obj; obj = obj->nobj)
			    if(obj->olet == foodsym)
				at(obj->ox, obj->oy, FOOD_SYM);
			prme();
			pline("Your nose tingles and you smell %s!",
				confused ? "something" : "food");
			more();
			docrt();
		}
		break;
	    }
	case SCR_IDENTIFY:
		/* known = TRUE; */
		if(confused)
			pline("You identify this as an identify scroll.");
		else
			pline("This is an identify scroll.");
		useup(scroll);
		objects[SCR_IDENTIFY].oc_name_known = 1;
		if(!confused)
		    while(
			!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
			&& invent
		    );
		return(1);
	case SCR_MAGIC_MAPPING:
	    {	register struct rm *lev;
		register int num, zx, zy;

		known = TRUE;
		pline("On this scroll %s a map!",
			confused ? "was" : "is");
		for(zy = 0; zy < ROWNO; zy++)
			for(zx = 0; zx < COLNO; zx++) {
				if(confused && rn2(7)) continue;
				lev = &(levl[zx][zy]);
				if((num = lev->typ) == 0)
					continue;
				if(num == SCORR) {
					lev->typ = CORR;
					lev->scrsym = CORR_SYM;
				} else
				if(num == SDOOR) {
					lev->typ = DOOR;
					lev->scrsym = '+';
					/* do sth in doors ? */
				} else if(lev->seen) continue;
#ifndef QUEST
				if(num != ROOM)
#endif QUEST
				{
				  lev->seen = lev->new = 1;
				  if(lev->scrsym == ' ' || !lev->scrsym)
				    newsym(zx,zy);
				  else
				    on_scr(zx,zy);
				}
			}
		break;
	    }
	case SCR_AMNESIA:
	    {	register int zx, zy;

		known = TRUE;
		for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
		    if(!confused || rn2(7))
			if(!cansee(zx,zy))
			    levl[zx][zy].seen = 0;
		docrt();
		pline("Thinking of Maud you forget everything else.");
		break;
	    }
	case SCR_FIRE:
	    {	register int num;
		register struct monst *mtmp;

		known = TRUE;
		if(confused) {
		    pline("The scroll catches fire and you burn your hands.");
		    losehp(1, "scroll of fire");
		} else {
		    pline("The scroll erupts in a tower of flame!");
		    if(Fire_resistance)
			pline("You are uninjured.");
		    else {
			num = rnd(6);
			u.uhpmax -= num;
			losehp(num, "scroll of fire");
		    }
		}
		num = (2*num + 1)/3;
		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
		    if(dist(mtmp->mx,mtmp->my) < 3) {
			mtmp->mhp -= num;
			if(index("FY", mtmp->data->mlet))
			    mtmp->mhp -= 3*num;	/* this might well kill 'F's */
			if(mtmp->mhp < 1) {
			    killed(mtmp);
			    break;		/* primitive */
			}
		    }
		}
		break;
	    }
	case SCR_PUNISHMENT:
		known = TRUE;
		if(confused) {
			pline("You feel guilty.");
			break;
		}
		pline("You are being punished for your misbehaviour!");
		if(Punished){
			pline("Your iron ball gets heavier.");
			uball->owt += 15;
			break;
		}
		Punished = INTRINSIC;
		setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
		setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
		uball->spe = 1;		/* special ball (see save) */
		break;
	default:
		impossible("What weird language is this written in? (%u)",
			scroll->otyp);
	}
	if(!objects[scroll->otyp].oc_name_known) {
		if(known && !confused) {
			objects[scroll->otyp].oc_name_known = 1;
			more_experienced(0,10);
		} else if(!objects[scroll->otyp].oc_uname)
			docall(scroll);
	}
	useup(scroll);
	return(1);
}

identify(otmp)		/* also called by newmail() */
register struct obj *otmp;
{
	objects[otmp->otyp].oc_name_known = 1;
	otmp->known = otmp->dknown = 1;
	prinv(otmp);
	return(1);
}

litroom(on)
register boolean on;
{
	register num,zx,zy;

	/* first produce the text (provided he is not blind) */
	if(Blind) goto do_it;
	if(!on) {
		if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
		    !levl[u.ux][u.uy].lit) {
			pline("It seems even darker in here than before.");
			return;
		} else
			pline("It suddenly becomes dark in here.");
	} else {
		if(u.uswallow){
			pline("%s's stomach is lit.", Monnam(u.ustuck));
			return;
		}
		if(!xdnstair){
			pline("Nothing Happens");
			return;
		}
#ifdef QUEST
		pline("The cave lights up around you, then fades.");
		return;
#else QUEST
		if(levl[u.ux][u.uy].typ == CORR) {
		    pline("The corridor lights up around you, then fades.");
		    return;
		} else if(levl[u.ux][u.uy].lit) {
		    pline("The light here seems better now.");
		    return;
		} else
		    pline("The room is lit.");
#endif QUEST
	}

do_it:
#ifdef QUEST
	return;
#else QUEST
	if(levl[u.ux][u.uy].lit == on)
		return;
	if(levl[u.ux][u.uy].typ == DOOR) {
		if(IS_ROOM(levl[u.ux][u.uy+1].typ)) zy = u.uy+1;
		else if(IS_ROOM(levl[u.ux][u.uy-1].typ)) zy = u.uy-1;
		else zy = u.uy;
		if(IS_ROOM(levl[u.ux+1][u.uy].typ)) zx = u.ux+1;
		else if(IS_ROOM(levl[u.ux-1][u.uy].typ)) zx = u.ux-1;
		else zx = u.ux;
	} else {
		zx = u.ux;
		zy = u.uy;
	}
	for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0;
		seelx--);
	for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0;
		seehx++);
	for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0;
		seely--);
	for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0;
		seehy++);
	for(zy = seely; zy <= seehy; zy++)
		for(zx = seelx; zx <= seehx; zx++) {
			levl[zx][zy].lit = on;
			if(!Blind && dist(zx,zy) > 2)
				if(on) prl(zx,zy); else nosee(zx,zy);
		}
	if(!on) seehx = 0;
#endif	QUEST
}
//E*O*F hack.read.c//

echo x - hack.rip.c
cat > "hack.rip.c" << '//E*O*F hack.rip.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.rip.c - version 1.0.2 */

#include <stdio.h>
#include "hack.h"

extern char plname[];

static char *rip[] = {
"                       ----------",
"                      /          \\",
"                     /    REST    \\",
"                    /      IN      \\",
"                   /     PEACE      \\",
"                  /                  \\",
"                  |                  |",
"                  |                  |",
"                  |                  |",
"                  |                  |",
"                  |                  |",
"                  |       1001       |",
"                 *|     *  *  *      | *",
"        _________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n",
0
};

outrip(){
	register char **dp = rip;
	register char *dpx;
	char buf[BUFSZ];
	register x,y;

	cls();
	(void) strcpy(buf, plname);
	buf[16] = 0;
	center(6, buf);
	(void) sprintf(buf, "%ld AU", u.ugold);
	center(7, buf);
	(void) sprintf(buf, "killed by%s",
		!strncmp(killer, "the ", 4) ? "" :
		!strcmp(killer, "starvation") ? "" :
		index(vowels, *killer) ? " an" : " a");
	center(8, buf);
	(void) strcpy(buf, killer);
	if(strlen(buf) > 16) {
	    register int i,i0,i1;
		i0 = i1 = 0;
		for(i = 0; i <= 16; i++)
			if(buf[i] == ' ') i0 = i, i1 = i+1;
		if(!i0) i0 = i1 = 16;
		buf[i1 + 16] = 0;
		center(10, buf+i1);
		buf[i0] = 0;
	}
	center(9, buf);
	(void) sprintf(buf, "%4d", getyear());
	center(11, buf);
	for(y=8; *dp; y++,dp++){
		x = 0;
		dpx = *dp;
		while(dpx[x]) {
			while(dpx[x] == ' ') x++;
			curs(x,y);
			while(dpx[x] && dpx[x] != ' '){
				extern int done_stopprint;
				if(done_stopprint)
					return;
				curx++;
				(void) putchar(dpx[x++]);
			}
		}
	}
	getret();
}

center(line, text) int line; char *text; {
register char *ip,*op;
	ip = text;
	op = &rip[line][28 - ((strlen(text)+1)/2)];
	while(*ip) *op++ = *ip++;
}
//E*O*F hack.rip.c//

echo x - hack.rumors.c
cat > "hack.rumors.c" << '//E*O*F hack.rumors.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.rumors.c - version 1.0.2 */

#include	<stdio.h>
#include	"config.h"
#define	CHARSZ	8	/* number of bits in a char */
#define	RUMORFILE	"rumors"
extern long *alloc();
extern char *index();
int n_rumors = 0;
int n_used_rumors = -1;
char *usedbits;

init_rumors(rumf) register FILE *rumf; {
register int i;
	n_used_rumors = 0;
	while(skipline(rumf)) n_rumors++;
	rewind(rumf);
	i = n_rumors/CHARSZ;
	usedbits = (char *) alloc((unsigned)(i+1));
	for( ; i>=0; i--) usedbits[i] = 0;
}

skipline(rumf) register FILE *rumf; {
char line[COLNO];
	while(1) {
		if(!fgets(line, sizeof(line), rumf)) return(0);
		if(index(line, '\n')) return(1);
	}
}

outline(rumf) register FILE *rumf; {
char line[COLNO];
register char *ep;
	if(!fgets(line, sizeof(line), rumf)) return;
	if((ep = index(line, '\n')) != 0) *ep = 0;
	pline("This cookie has a scrap of paper inside! It reads: ");
	pline(line);
}

outrumor(){
register int rn,i;
register FILE *rumf;
	if(n_rumors <= n_used_rumors ||
	  (rumf = fopen(RUMORFILE, "r")) == (FILE *) 0) return;
	if(n_used_rumors < 0) init_rumors(rumf);
	if(!n_rumors) goto none;
	rn = rn2(n_rumors - n_used_rumors);
	i = 0;
	while(rn || used(i)) {
		(void) skipline(rumf);
		if(!used(i)) rn--;
		i++;
	}
	usedbits[i/CHARSZ] |= (1 << (i % CHARSZ));
	n_used_rumors++;
	outline(rumf);
none:
	(void) fclose(rumf);
}

used(i) register int i; {
	return(usedbits[i/CHARSZ] & (1 << (i % CHARSZ)));
}
//E*O*F hack.rumors.c//

echo x - hack.save.c
cat > "hack.save.c" << '//E*O*F hack.save.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.save.c - version 1.0.2 */

#include "hack.h"
extern char genocided[60];	/* defined in Decl.c */
extern char fut_geno[60];	/* idem */
#include <signal.h>

extern char SAVEF[], nul[];
extern char pl_character[PL_CSIZ];
extern long lseek();
extern struct obj *restobjchn();
extern struct monst *restmonchn();

dosave(){
	if(dosave0(0)) {
		settty("Be seeing you ...\n");
		exit(0);
	}
#ifdef lint
	return(0);
#endif lint
}

#ifndef NOSAVEONHANGUP
hangup(){
	(void) dosave0(1);
	exit(1);
}
#endif NOSAVEONHANGUP

/* returns 1 if save successful */
dosave0(hu) int hu; {
	register fd, ofd;
	int tmp;		/* not register ! */

	(void) signal(SIGHUP, SIG_IGN);
	(void) signal(SIGINT, SIG_IGN);
	if((fd = creat(SAVEF, FMASK)) < 0) {
		if(!hu) pline("Cannot open save file. (Continue or Quit)");
		return(0);
	}
	savelev(fd,dlevel);
	saveobjchn(fd, invent);
	saveobjchn(fd, fcobj);
	savemonchn(fd, fallen_down);
	tmp = getuid();
	bwrite(fd, (char *) &tmp, sizeof tmp);
	bwrite(fd, (char *) &flags, sizeof(struct flag));
	bwrite(fd, (char *) &dlevel, sizeof dlevel);
	bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel);
	bwrite(fd, (char *) &moves, sizeof moves);
	bwrite(fd, (char *) &u, sizeof(struct you));
	if(u.ustuck)
		bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id);
	bwrite(fd, (char *) pl_character, sizeof pl_character);
	bwrite(fd, (char *) genocided, sizeof genocided);
	bwrite(fd, (char *) fut_geno, sizeof fut_geno);
	savenames(fd);
	for(tmp = 1; tmp <= maxdlevel; tmp++) {
		extern int hackpid;
		extern boolean level_exists[];

		if(tmp == dlevel || !level_exists[tmp]) continue;
		glo(tmp);
		if((ofd = open(lock, 0)) < 0) {
		    if(!hu) pline("Error while saving: cannot read %s.", lock);
		    (void) close(fd);
		    (void) unlink(SAVEF);
		    if(!hu) done("tricked");
		    return(0);
		}
		getlev(ofd, hackpid, tmp);
		(void) close(ofd);
		bwrite(fd, (char *) &tmp, sizeof tmp);	/* level number */
		savelev(fd,tmp);			/* actual level */
		(void) unlink(lock);
	}
	(void) close(fd);
	{ register char *lp = index(lock, '.');
	  if(lp) *lp = 0;
	  (void) unlink(lock);
	}
	return(1);
}

dorecover(fd)
register fd;
{
	register nfd;
	int tmp;		/* not a register ! */
	unsigned mid;		/* idem */
	struct obj *otmp;

	getlev(fd, 0, 0);
	invent = restobjchn(fd);
	for(otmp = invent; otmp; otmp = otmp->nobj)
		if(otmp->owornmask)
			setworn(otmp, otmp->owornmask);
	fcobj = restobjchn(fd);
	fallen_down = restmonchn(fd);
	mread(fd, (char *) &tmp, sizeof tmp);
	if(tmp != getuid()) {		/* strange ... */
		(void) close(fd);
		(void) unlink(SAVEF);
		puts("Saved game was not yours.");
		return(0);
	}
	mread(fd, (char *) &flags, sizeof(struct flag));
	mread(fd, (char *) &dlevel, sizeof dlevel);
	mread(fd, (char *) &maxdlevel, sizeof maxdlevel);
	mread(fd, (char *) &moves, sizeof moves);
	mread(fd, (char *) &u, sizeof(struct you));
	if(u.ustuck)
		mread(fd, (char *) &mid, sizeof mid);
	mread(fd, (char *) pl_character, sizeof pl_character);
	mread(fd, (char *) genocided, sizeof genocided);
	mread(fd, (char *) fut_geno, sizeof fut_geno);
	restnames(fd);
	while(1) {
		if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp)
			break;
		getlev(fd, 0, tmp);
		glo(tmp);
		if((nfd = creat(lock, FMASK)) < 0)
			panic("Cannot open temp file %s!\n", lock);
		savelev(nfd,tmp);
		(void) close(nfd);
	}
	(void) lseek(fd, 0L, 0);
	getlev(fd, 0, 0);
	(void) close(fd);
	(void) unlink(SAVEF);
	if(Punished) {
		for(otmp = fobj; otmp; otmp = otmp->nobj)
			if(otmp->olet == CHAIN_SYM) goto chainfnd;
		panic("Cannot find the iron chain?");
	chainfnd:
		uchain = otmp;
		if(!uball){
			for(otmp = fobj; otmp; otmp = otmp->nobj)
				if(otmp->olet == BALL_SYM && otmp->spe)
					goto ballfnd;
			panic("Cannot find the iron ball?");
		ballfnd:
			uball = otmp;
		}
	}
	if(u.ustuck) {
		register struct monst *mtmp;

		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
			if(mtmp->m_id == mid) goto monfnd;
		panic("Cannot find the monster ustuck.");
	monfnd:
		u.ustuck = mtmp;
	}
#ifndef QUEST
	setsee();  /* only to recompute seelx etc. - these weren't saved */
#endif QUEST
	docrt();
	return(1);
}

struct obj *
restobjchn(fd)
register fd;
{
	register struct obj *otmp, *otmp2;
	register struct obj *first = 0;
	int xl;
#ifdef lint
	/* suppress "used before set" warning from lint */
	otmp2 = 0;
#endif lint
	while(1) {
		mread(fd, (char *) &xl, sizeof(xl));
		if(xl == -1) break;
		otmp = newobj(xl);
		if(!first) first = otmp;
		else otmp2->nobj = otmp;
		mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj));
		otmp2 = otmp;
	}
	if(first && otmp2->nobj){
		impossible("Restobjchn: error reading objchn.");
		otmp2->nobj = 0;
	}
	return(first);
}

struct monst *
restmonchn(fd)
register fd;
{
	register struct monst *mtmp, *mtmp2;
	register struct monst *first = 0;
	int xl;

	struct permonst *monbegin;
	long differ;

	mread(fd, (char *)&monbegin, sizeof(monbegin));
	differ = (char *)(&mons[0]) - (char *)(monbegin);

#ifdef lint
	/* suppress "used before set" warning from lint */
	mtmp2 = 0;
#endif lint
	while(1) {
		mread(fd, (char *) &xl, sizeof(xl));
		if(xl == -1) break;
		mtmp = newmonst(xl);
		if(!first) first = mtmp;
		else mtmp2->nmon = mtmp;
		mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst));
		mtmp->data = (struct permonst *)
			((char *) mtmp->data + differ);
		if(mtmp->minvent)
			mtmp->minvent = restobjchn(fd);
		mtmp2 = mtmp;
	}
	if(first && mtmp2->nmon){
		impossible("Restmonchn: error reading monchn.");
		mtmp2->nmon = 0;
	}
	return(first);
}
//E*O*F hack.save.c//

echo x - hack.search.c
cat > "hack.search.c" << '//E*O*F hack.search.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.search.c - version 1.0.2 */

#include "hack.h"

extern struct monst *makemon();

findit()	/* returns number of things found */
{
	int num;
	register xchar zx,zy;
	register struct trap *ttmp;
	register struct monst *mtmp;
	xchar lx,hx,ly,hy;

	if(u.uswallow) return(0);
	for(lx = u.ux; (num = levl[lx-1][u.uy].typ) && num != CORR; lx--) ;
	for(hx = u.ux; (num = levl[hx+1][u.uy].typ) && num != CORR; hx++) ;
	for(ly = u.uy; (num = levl[u.ux][ly-1].typ) && num != CORR; ly--) ;
	for(hy = u.uy; (num = levl[u.ux][hy+1].typ) && num != CORR; hy++) ;
	num = 0;
	for(zy = ly; zy <= hy; zy++)
		for(zx = lx; zx <= hx; zx++) {
			if(levl[zx][zy].typ == SDOOR) {
				levl[zx][zy].typ = DOOR;
				atl(zx, zy, '+');
				num++;
			} else if(levl[zx][zy].typ == SCORR) {
				levl[zx][zy].typ = CORR;
				atl(zx, zy, CORR_SYM);
				num++;
			} else if(ttmp = t_at(zx, zy)) {
				if(ttmp->ttyp == PIERC){
					(void) makemon(PM_PIERCER, zx, zy);
					num++;
					deltrap(ttmp);
				} else if(!ttmp->tseen) {
					ttmp->tseen = 1;
					if(!vism_at(zx, zy))
						atl(zx,zy,'^');
					num++;
				}
			} else if(mtmp = m_at(zx,zy)) if(mtmp->mimic){
				seemimic(mtmp);
				num++;
			}
		}
	return(num);
}

dosearch()
{
	register xchar x,y;
	register struct trap *trap;
	register struct monst *mtmp;

	for(x = u.ux-1; x < u.ux+2; x++)
	for(y = u.uy-1; y < u.uy+2; y++) if(x != u.ux || y != u.uy) {
		if(levl[x][y].typ == SDOOR) {
			if(rn2(7)) continue;
			levl[x][y].typ = DOOR;
			levl[x][y].seen = 0;	/* force prl */
			prl(x,y);
			nomul(0);
		} else if(levl[x][y].typ == SCORR) {
			if(rn2(7)) continue;
			levl[x][y].typ = CORR;
			levl[x][y].seen = 0;	/* force prl */
			prl(x,y);
			nomul(0);
		} else {
		/* Be careful not to find anything in an SCORR or SDOOR */
			if(mtmp = m_at(x,y)) if(mtmp->mimic){
				seemimic(mtmp);
				pline("You find a mimic.");
				return(1);
			}
			for(trap = ftrap; trap; trap = trap->ntrap)
			if(trap->tx == x && trap->ty == y &&
			   !trap->tseen && !rn2(8)) {
				nomul(0);
				pline("You find a%s.", traps[trap->ttyp]);
				if(trap->ttyp == PIERC) {
					deltrap(trap);
					(void) makemon(PM_PIERCER,x,y);
					return(1);
				}
				trap->tseen = 1;
				if(!vism_at(x,y)) atl(x,y,'^');
			}
		}
	}
	return(1);
}

/* ARGSUSED */
doidtrap(str) /* register */ char *str; {
register struct trap *trap;
register int x,y;
	if(!getdir(1)) return(0);
	x = u.ux + u.dx;
	y = u.uy + u.dy;
	for(trap = ftrap; trap; trap = trap->ntrap)
		if(trap->tx == x && trap->ty == y && trap->tseen) {
		    if(u.dz)
			if((u.dz < 0) != (!xdnstair && trap->ttyp == TRAPDOOR))
			    continue;
		    pline("That is a%s.", traps[trap->ttyp]);
		    return(0);
		}
	pline("I can't see a trap there.");
	return(0);
}

wakeup(mtmp)
register struct monst *mtmp;
{
	mtmp->msleep = 0;
	setmangry(mtmp);
	if(mtmp->mimic) seemimic(mtmp);
}

/* NOTE: we must check if(mtmp->mimic) before calling this routine */
seemimic(mtmp)
register struct monst *mtmp;
{
		mtmp->mimic = 0;
		mtmp->mappearance = 0;
		unpmon(mtmp);
		pmon(mtmp);
}
//E*O*F hack.search.c//

echo x - hack.shknam.c
cat > "hack.shknam.c" << '//E*O*F hack.shknam.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.shknam.c - version 1.0.2 */

#include "hack.h"

char *shkliquors[] = {
	/* Ukraine */
	"Njezjin", "Tsjernigof", "Gomel", "Ossipewsk", "Gorlowka",
	/* N. Russia */
	"Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja",
	"Narodnaja", "Kyzyl",
	/* Silezie */
	"Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice",
	"Brzeg", "Krnov", "Hradec Kralove",
	/* Schweiz */
	"Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm",
	"Flims", "Vals", "Schuls", "Zum Loch",
	0
};

char *shkbooks[] = {
	/* Eire */
	"Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch",
	"Loughrea", "Croagh", "Maumakeogh", "Ballyjamesduff",
	"Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra",
	"Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan",
	"Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh",
	"Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea",
	"Culdaff", "Dunfanaghy", "Inishbofin", "Kesh",
	0
};

char *shkarmors[] = {
	/* Turquie */
	"Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep",
	"Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak",
	"Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt",
	"Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni",
	"Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat",
	"Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan",
	0
};

char *shkwands[] = {
	/* Wales */
	"Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach",
	"Rhaeader", "Llandrindod", "Llanfair-ym-muallt",
	"Y-Fenni", "Measteg", "Rhydaman", "Beddgelert",
	"Curig", "Llanrwst", "Llanerchymedd", "Caergybi",
	/* Scotland */
	"Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar",
	"Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven",
	"Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch",
	"Kyleakin", "Dunvegan",
	0
};

char *shkrings[] = {
	/* Hollandse familienamen */
	"Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken",
	"Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy",
	"Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix",
	"Ypey",
	/* Skandinaviske navne */
	"Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko",
	"Enontekis", "Rovaniemi", "Avasaksa", "Haparanda",
	"Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske",
	0
};

char *shkfoods[] = {
	/* Indonesia */
	"Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan",
	"Bandjar", "Parbalingga", "Bojolali", "Sarangan",
	"Ngebel", "Djombang", "Ardjawinangun", "Berbek",
	"Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi",
	"Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan",
	"Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe",
	"Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe",
	0
};

char *shkweapons[] = {
	/* Perigord */
	"Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard",
	"Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac",
	"Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac",
	"Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac",
	"Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon",
	"Eymoutiers", "Eygurande", "Eauze", "Labouheyre",
	0
};

char *shkgeneral[] = {
	/* Suriname */
	"Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi",
	"Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo",
	"Akalapi", "Sipaliwini",
	/* Greenland */
	"Annootok", "Upernavik", "Angmagssalik",
	/* N. Canada */
	"Aklavik", "Inuvik", "Tuktoyaktuk",
	"Chicoutimi", "Ouiatchouane", "Chibougamau",
	"Matagami", "Kipawa", "Kinojevis",
	"Abitibi", "Maganasipi",
	/* Iceland */
	"Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri",
	"Holmavik",
	0
};

struct shk_nx {
	char x;
	char **xn;
} shk_nx[] = {
	{ POTION_SYM,	shkliquors },
	{ SCROLL_SYM,	shkbooks },
	{ ARMOR_SYM,	shkarmors },
	{ WAND_SYM,	shkwands },
	{ RING_SYM,	shkrings },
	{ FOOD_SYM,	shkfoods },
	{ WEAPON_SYM,	shkweapons },
	{ 0,		shkgeneral }
};

findname(nampt, let) char *nampt; char let; {
register struct shk_nx *p = shk_nx;
register char **q;
register int i;
	while(p->x && p->x != let) p++;
	q = p->xn;
	for(i=0; i<dlevel; i++) if(!q[i]){
		/* Not enough names, try general name */
		if(let) findname(nampt, 0);
		else (void) strcpy(nampt, "Dirk");
		return;
	}
	(void) strncpy(nampt, q[i], PL_NSIZ);
	nampt[PL_NSIZ-1] = 0;
}
//E*O*F hack.shknam.c//

echo x - hack.steal.c
cat > "hack.steal.c" << '//E*O*F hack.steal.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* hack.steal.c - version 1.0.2 */

#include "hack.h"

long		/* actually returns something that fits in an int */
somegold(){
	return( (u.ugold < 100) ? u.ugold :
		(u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) );
}

stealgold(mtmp)  register struct monst *mtmp; {
register struct gold *gold = g_at(u.ux, u.uy);
register long tmp;
	if(gold && ( !u.ugold || gold->amount > u.ugold || !rn2(5))) {
		mtmp->mgold += gold->amount;
		freegold(gold);
		if(Invis) newsym(u.ux, u.uy);
		pline("%s quickly snatches some gold from between your feet!",
			Monnam(mtmp));
		if(!u.ugold || !rn2(5)) {
			rloc(mtmp);
			mtmp->mflee = 1;
		}
	} else if(u.ugold) {
		u.ugold -= (tmp = somegold());
		pline("Your purse feels lighter.");
		mtmp->mgold += tmp;
		rloc(mtmp);
		mtmp->mflee = 1;
		flags.botl = 1;
	}
}

/* steal armor after he finishes taking it off */
unsigned stealoid;		/* object to be stolen */
unsigned stealmid;		/* monster doing the stealing */
stealarm(){
	register struct monst *mtmp;
	register struct obj *otmp;

	for(otmp = invent; otmp; otmp = otmp->nobj)
	  if(otmp->o_id == stealoid) {
	    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
	      if(mtmp->m_id == stealmid) {
		if(dist(mtmp->mx,mtmp->my) < 3) {
		  freeinv(otmp);
		  pline("%s steals %s!", Monnam(mtmp), doname(otmp));
		  mpickobj(mtmp,otmp);
		  mtmp->mflee = 1;
		  rloc(mtmp);
		}
		break;
	      }
	    break;
	  }
	stealoid = 0;
}

/* returns 1 when something was stolen */
/* (or at least, when N should flee now) */
/* avoid stealing the object stealoid */
steal(mtmp)
struct monst *mtmp;
{
	register struct obj *otmp;
	register tmp;
	register named = 0;

	if(!invent){
	    if(Blind)
	      pline("Somebody tries to rob you, but finds nothing to steal.");
	    else
	      pline("%s tries to rob you, but she finds nothing to steal!",
		Monnam(mtmp));
	    return(1);	/* let her flee */
	}
	tmp = 0;
	for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2)
		tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1);
	tmp = rn2(tmp);
	for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2)
		if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1))
			< 0) break;
	if(!otmp) {
		impossible("Steal fails!");
		return(0);
	}
	if(otmp->o_id == stealoid)
		return(0);
	if((otmp->owornmask & (W_ARMOR | W_RING))){
		switch(otmp->olet) {
		case RING_SYM:
			ringoff(otmp);
			break;
		case ARMOR_SYM:
			if(multi < 0 || otmp == uarms){
			  setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
			  break;
			}
		{ int curssv = otmp->cursed;
			otmp->cursed = 0;
			stop_occupation();
			pline("%s seduces you and %s off your %s.",
				Amonnam(mtmp, Blind ? "gentle" : "beautiful"),
				otmp->cursed ? "helps you to take"
					    : "you start taking",
				(otmp == uarmg) ? "gloves" :
				(otmp == uarmh) ? "helmet" : "armor");
			named++;
			(void) armoroff(otmp);
			otmp->cursed = curssv;
			if(multi < 0){
				extern char *nomovemsg;
				extern int (*afternmv)();
				/*
				multi = 0;
				nomovemsg = 0;
				afternmv = 0;
				*/
				stealoid = otmp->o_id;
				stealmid = mtmp->m_id;
				afternmv = stealarm;
				return(0);
			}
			break;
		}
		default:
			impossible("Tried to steal a strange worn thing.");
		}
	}
	else if(otmp == uwep)
		setuwep((struct obj *) 0);
	if(otmp->olet == CHAIN_SYM) {
		impossible("How come you are carrying that chain?");
	}
	if(Punished && otmp == uball){
		Punished = 0;
		freeobj(uchain);
		free((char *) uchain);
		uchain = (struct obj *) 0;
		uball->spe = 0;
		uball = (struct obj *) 0;	/* superfluous */
	}
	freeinv(otmp);
	pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp));
	mpickobj(mtmp,otmp);
	return((multi < 0) ? 0 : 1);
}

mpickobj(mtmp,otmp)
register struct monst *mtmp;
register struct obj *otmp;
{
	otmp->nobj = mtmp->minvent;
	mtmp->minvent = otmp;
}

stealamulet(mtmp)
register struct monst *mtmp;
{
	register struct obj *otmp;

	for(otmp = invent; otmp; otmp = otmp->nobj) {
	    if(otmp->olet == AMULET_SYM) {
		/* might be an imitation one */
		if(otmp == uwep) setuwep((struct obj *) 0);
		freeinv(otmp);
		mpickobj(mtmp,otmp);
		pline("%s stole %s!", Monnam(mtmp), doname(otmp));
		return(1);
	    }
	}
	return(0);
}

/* release the objects the killed animal has stolen */
relobj(mtmp,show)
register struct monst *mtmp;
register show;
{
	register struct obj *otmp, *otmp2;

	for(otmp = mtmp->minvent; otmp; otmp = otmp2){
		otmp->ox = mtmp->mx;
		otmp->oy = mtmp->my;
		otmp2 = otmp->nobj;
		otmp->nobj = fobj;
		fobj = otmp;
		stackobj(fobj);
		if(show & cansee(mtmp->mx,mtmp->my))
			atl(otmp->ox,otmp->oy,otmp->olet);
	}
	mtmp->minvent = (struct obj *) 0;
	if(mtmp->mgold || mtmp->data->mlet == 'L') {
		register long tmp;

		tmp = (mtmp->mgold > 10000) ? 10000 : mtmp->mgold;
		mkgold((long)(tmp + d(dlevel,30)), mtmp->mx, mtmp->my);
		if(show & cansee(mtmp->mx,mtmp->my))
			atl(mtmp->mx,mtmp->my,'$');
	}
}
//E*O*F hack.steal.c//

exit 0