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

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

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



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 8 (of 56)."
# Contents:  src/prisym.c src/trap.c
# Wrapped by billr@saab on Wed Jul 11 17:11:00 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/prisym.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/prisym.c'\"
else
echo shar: Extracting \"'src/prisym.c'\" \(12560 characters\)
sed "s/^X//" >'src/prisym.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)prisym.c	3.0	89/11/15
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X
X#ifdef WORM
X#include "wseg.h"
X#include "lev.h"
X
XSTATIC_DCL void FDECL(pwseg, (struct wseg *));
X#endif
X
X#ifdef OVL0
X
Xvoid
Xatl(x,y,ch)
Xregister int x, y;
Xchar ch;
X{
X	register struct rm *crm = &levl[x][y];
X
X	if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){
X		impossible("atl(%d,%d,%c)",x,y,ch);
X		return;
X	}
X	if(crm->seen && crm->scrsym == ch) return;
X	/* crm->scrsym = (uchar) ch; */
X	/* wrong if characters are signed but uchar is larger than char,
X	 * and ch, when passed, was greater than 127.
X	 * We probably should _really_ go around changing atl to take a
X	 * uchar for its third argument...
X	 */
X	crm->scrsym = (uchar)((unsigned char) ch);
X	crm->new = 1;
X	on_scr(x,y);
X}
X
Xvoid
Xon_scr(x,y)
Xregister int x, y;
X{
X	if(x < scrlx) scrlx = x;
X	if(x > scrhx) scrhx = x;
X	if(y < scrly) scrly = y;
X	if(y > scrhy) scrhy = y;
X}
X
X#endif /* OVL0 */
X#ifdef OVL2
X
X/* call: (x,y) - display
X	(-1,0) - close (leave last symbol)
X	(-1,-1)- close (undo last symbol)
X	(-1,let)-open: initialize symbol
X	(-2,let)-change let
X	(-3,let)-set color
X*/
X
Xvoid
Xtmp_at(x, y)
Xint x, y;
X{
X#ifdef LINT	/* static schar prevx, prevy; static char let; */
Xschar prevx=0, prevy=0;
Xuchar let;
Xuchar col;
X#else
Xstatic schar NEARDATA prevx, NEARDATA prevy;
Xstatic uchar NEARDATA let;
Xstatic uchar NEARDATA col;
X#endif
X
X	switch ((int)x) {
X	    case -2:		/* change let call */
X		let = y;
X		return;
X	    case -1:		/* open or close call */
X		if ((int)y >= 0) {
X		    let = y;
X		    prevx = -1;
X		    col = AT_ZAP;
X		    return;
X		}
X		break;
X	    case -3:		/* set color call */
X		col = y;
X		return;
X	}
X	if(prevx >= 0 && cansee(prevx,prevy)) {
X		delay_output();
X		prl(prevx, prevy);	/* in case there was a monster */
X		at(prevx, prevy, levl[prevx][prevy].scrsym, AT_APP);
X	}
X	if(x >= 0){	/* normal call */
X		if(cansee(x,y)) at(x,y,let,col);
X		prevx = x;
X		prevy = y;
X	} else {	/* close call */
X		let = 0;
X		prevx = -1;
X	}
X}
X
X/* like the previous, but the symbols are first erased on completion */
Xvoid
XTmp_at2(x, y)
Xint x, y;
X{
X#ifdef LINT	/* static char let; static xchar cnt; static coord tc[COLNO]; */
Xuchar let;
Xxchar cnt;
Xcoord tc[COLNO];	/* but watch reflecting beams! */
X# ifdef TEXTCOLOR
Xuchar col;
X# endif
X#else
Xstatic uchar NEARDATA let;
Xstatic xchar NEARDATA cnt;
Xstatic coord NEARDATA tc[COLNO];	/* but watch reflecting beams! */
X# ifdef TEXTCOLOR
Xstatic uchar NEARDATA col;
X# endif
X#endif
Xregister int xx,yy;
X	switch((int)x) {
X	    case -1:
X		if(y > 0) {	/* open call */
X			let = y;
X			cnt = 0;
X#ifdef TEXTCOLOR
X			col = AT_ZAP;
X#endif
X			return;
X		}
X		/* close call (do not distinguish y==0 and y==-1) */
X		while(cnt--) {
X			xx = tc[cnt].x;
X			yy = tc[cnt].y;
X			prl(xx, yy);
X			at(xx, yy, levl[xx][yy].scrsym, AT_APP);
X		}
X		cnt = let = 0;	/* superfluous */
X		return;
X	    case -2:		/* change let call */
X		let = y;
X		return;
X#ifdef TEXTCOLOR
X	    case -3:		/* set color call */
X		col = y;
X		return;
X#endif
X	}
X	/* normal call */
X	if(cansee(x,y)) {
X		if(cnt) delay_output();
X#ifdef TEXTCOLOR
X		at(x,y,let,col);
X#else
X		at(x,y,let,AT_ZAP);
X#endif
X		tc[cnt].x = x;
X		tc[cnt].y = y;
X		if(++cnt >= COLNO) panic("Tmp_at2 overflow?");
X		levl[x][y].new = 0;	/* prevent pline-nscr erasing --- */
X	}
X}
X
X#endif /* OVL2 */
X#ifdef OVL1
X
Xvoid
Xcurs_on_u()
X{
X#ifdef CLIPPING
X	cliparound(u.ux, u.uy);
X	(void)win_curs(u.ux, u.uy);
X#else
X	curs(u.ux, u.uy+2);
X#endif
X}
X
Xvoid
Xpru()
X{
X	if(u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy))
X		/* if(! levl[u.udisx][u.udisy].new) */
X			if(!vism_at(u.udisx, u.udisy))
X				newsym(u.udisx, u.udisy);
X	if(Invisible
X#ifdef POLYSELF
X			|| u.uundetected
X#endif
X					) {
X		u.udispl = 0;
X		prl(u.ux,u.uy);
X	} else
X	if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) {
X		atl(u.ux, u.uy, (char) u.usym);
X		u.udispl = 1;
X		u.udisx = u.ux;
X		u.udisy = u.uy;
X	}
X	levl[u.ux][u.uy].seen = 1;
X}
X
X#endif /* OVL1 */
X#ifdef OVL0
X
X/* print a position that is visible for @ */
Xvoid
Xprl(x,y)
Xint x, y;
X{
X	register struct rm *room;
X	register struct monst *mtmp = (struct monst *)0;
X	register struct obj *otmp;
X	register struct trap *ttmp;
X
X	if(x == u.ux && y == u.uy && !Invisible
X#ifdef POLYSELF
X						&& !u.uundetected
X#endif
X								) {
X		pru();
X		return;
X	}
X	if(!isok(x,y)) return;
X	room = &levl[x][y];
X	if((!room->typ) ||
X	   (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR &&
X				  !levl[u.ux][u.uy].lit))
X	    /* the only lit corridor squares should be the entrances to
X	     * outside castle areas */
X		return;
X	if(MON_AT(x, y)) mtmp = m_at(x,y);
X	if(mtmp && !mtmp->mhide &&
X		(!mtmp->minvis || See_invisible)) {
X#ifdef WORM
X		if(m_atseg)
X			pwseg(m_atseg);
X		else
X#endif
X		pmon(mtmp);
X	}
X	else if(OBJ_AT(x, y) && !is_pool(x,y)) {
X		otmp = level.objects[x][y];
X		atl(x,y,Hallucination ? rndobjsym() : otmp->olet);
X	}
X	else if(room->gmask && !is_pool(x,y))
X		atl(x,y,Hallucination ? rndobjsym() : GOLD_SYM);
X	else if((!mtmp || mtmp->data == &mons[PM_GIANT_SPIDER]) &&
X		  (ttmp = t_at(x,y)) && ttmp->ttyp == WEB)
X		atl(x,y,(char)WEB_SYM);
X	else if(mtmp && (!mtmp->minvis || See_invisible)) {
X		/* must be a hiding monster, but not hiding right now */
X		/* assume for the moment that long worms do not hide */
X		pmon(mtmp);
X	}
X	else if(!room->seen || room->scrsym == STONE_SYM) {
X		room->new = room->seen = 1;
X		newsym(x,y);
X		on_scr(x,y);
X	}
X	room->seen = 1;
X}
X
Xuchar
Xnews0(x,y)
Xregister xchar x,y;
X{
X	register struct obj *otmp;
X	register struct trap *ttmp;
X	struct rm *room;
X	register uchar tmp;	/* don't compare char with uchar -- OIS */
X	register int croom;
X
X	room = &levl[x][y];
X	/* note: a zero scrsym means to ignore the presence of objects */
X	if(!room->seen) tmp = STONE_SYM;
X	else if(room->typ == POOL || room->typ == MOAT) tmp = POOL_SYM;
X	else if(OBJ_AT(x, y) && !Blind && room->scrsym) {
X		otmp = level.objects[x][y];
X		tmp = Hallucination ? rndobjsym() : otmp->olet;
X	}
X	else if(room->gmask && !Blind && room->scrsym) 
X		tmp = Hallucination ? rndobjsym() : GOLD_SYM;
X	else if(x == xupstair && y == yupstair) tmp = UP_SYM;
X	else if(x == xdnstair && y == ydnstair) tmp = DN_SYM;
X#ifdef STRONGHOLD
X	else if(x == xupladder && y == yupladder) tmp = UPLADDER_SYM;
X	else if(x == xdnladder && y == ydnladder) tmp = DNLADDER_SYM;
X#endif
X	else if((ttmp = t_at(x,y)) && ttmp->ttyp == WEB) tmp = WEB_SYM;
X	else if(ttmp && ttmp->tseen) tmp = TRAP_SYM;
X	else switch(room->typ) {
X	case SCORR:
X		tmp = ' ';	/* _not_ STONE_SYM! */
X		break;
X	case SDOOR:
X		croom = inroom(x,y);
X		if(croom == -1) {
X#ifdef STRONGHOLD
X			if(IS_WALL(levl[x-1][y].typ)) tmp = HWALL_SYM;
X			else tmp = VWALL_SYM;
X			break;
X#else
X			impossible("door %d %d not in room",x,y);
X#endif
X		}
X		if(rooms[croom].lx-1 == x || rooms[croom].hx+1 == x)
X			tmp = VWALL_SYM;
X		else	/* SDOORs aren't created on corners */
X			tmp = HWALL_SYM;
X  		break;
X	case HWALL:
X#ifdef STRONGHOLD
X		if (is_maze_lev && is_drawbridge_wall(x,y) >= 0) tmp = DB_HWALL_SYM;
X		else
X#endif
X		tmp = HWALL_SYM;
X		break;
X	case VWALL:
X#ifdef STRONGHOLD
X		if (is_maze_lev && is_drawbridge_wall(x,y) >= 0) tmp = DB_VWALL_SYM;
X		else
X#endif
X		tmp = VWALL_SYM;
X		break;
X	case TLCORNER:
X		tmp = TLCORN_SYM;
X		break;
X	case TRCORNER:
X		tmp = TRCORN_SYM;
X		break;
X	case BLCORNER:
X		tmp = BLCORN_SYM;
X		break;
X	case BRCORNER:
X		tmp = BRCORN_SYM;
X		break;
X	case DOOR:
X		if (room->doormask == D_NODOOR || room->doormask & D_BROKEN)
X		    tmp = NO_DOOR_SYM;
X		else if (room->doormask & (D_CLOSED|D_LOCKED))
X		    tmp = CLOSED_DOOR_SYM;
X		/* We know door is open. */
X		else {
X		    croom=inroom(x,y);
X		    if(croom == -1) {
X#ifdef STRONGHOLD
X			if(IS_WALL(levl[x-1][y].typ)||IS_WALL(levl[x+1][y].typ))
X			    tmp = H_OPEN_DOOR_SYM;
X			else
X			    tmp = V_OPEN_DOOR_SYM;
X#else
X			impossible("door %d %d not in room",x,y);
X#endif
X		    } else if(rooms[croom].ly<=y && y<=rooms[croom].hy)
X			tmp = V_OPEN_DOOR_SYM;
X		    else
X			tmp = H_OPEN_DOOR_SYM;
X		}
X		break;
X	case CORR:
X		tmp = CORR_SYM;
X		break;
X#ifdef STRONGHOLD
X	case DRAWBRIDGE_UP:
X		if((room->drawbridgemask & DB_UNDER) == DB_MOAT) tmp = POOL_SYM;
X		else tmp = ROOM_SYM;
X		break;
X	case DRAWBRIDGE_DOWN:
X#endif /* STRONGHOLD /**/
X	case ROOM:
X		if(room->lit || cansee(x,y) || Blind) tmp = ROOM_SYM;
X		else tmp = STONE_SYM;
X		break;
X#ifdef POLYSELF
X	case STONE:
X		tmp = STONE_SYM;
X		break;
X#endif
X#ifdef FOUNTAINS
X	case FOUNTAIN:
X		tmp = FOUNTAIN_SYM;
X		break;
X#endif
X#ifdef THRONES
X	case THRONE:
X		tmp = THRONE_SYM;
X		break;
X#endif
X#ifdef SINKS
X	case SINK:
X		tmp = SINK_SYM;
X		break;
X#endif
X#ifdef ALTARS
X	case ALTAR:
X		tmp = ALTAR_SYM;
X		break;
X#endif
X	case CROSSWALL:
X		tmp = CRWALL_SYM;
X		break;
X	case TUWALL:
X		tmp = TUWALL_SYM;
X		break;
X	case TDWALL:
X		tmp = TDWALL_SYM;
X		break;
X	case TLWALL:
X		tmp = TLWALL_SYM;
X		break;
X	case TRWALL:
X		tmp = TRWALL_SYM;
X		break;
X/*
X	case POOL:
X		tmp = POOL_SYM;
X		break;
X*/
X	default:
X		tmp = ERRCHAR;
X	}
X	return(tmp);
X}
X
Xvoid
Xnewsym(x,y)
Xregister int x, y;
X{
X	atl(x,y,(char)news0(x,y));
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X/* used with wand of digging (or pick-axe): fill scrsym and force display */
X/* also when a POOL evaporates */
Xvoid
Xmnewsym(x, y)
Xregister int x, y;
X{
X	register struct rm *room;
X	uchar newscrsym;	/* OIS */
X
X	if(!vism_at(x,y)) {
X		room = &levl[x][y];
X		newscrsym = news0(x,y);
X		if(room->scrsym != newscrsym) {
X			room->scrsym = newscrsym;
X			room->seen = 0;
X		}
X	}
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xvoid
Xnosee(x,y)
Xregister int x, y;
X{
X	register struct rm *room;
X
X	if(!isok(x,y)) return;
X	room = &levl[x][y];
X	if(levl[x][y].scrsym == ROOM_SYM
X	   && !room->lit && !Blind) {
X		room->scrsym = STONE_SYM;	/* was ' ' -- OIS */
X		room->new = 1;
X		on_scr(x,y);
X	}
X}
X
Xvoid
Xprl1(x,y)
Xregister int x, y;
X{
X	if(u.dx) {
X		if(u.dy) {
X			prl(x-(2*u.dx),y);
X			prl(x-u.dx,y);
X			prl(x,y);
X			prl(x,y-u.dy);
X			prl(x,y-(2*u.dy));
X		} else {
X			prl(x,y-1);
X			prl(x,y);
X			prl(x,y+1);
X		}
X	} else {
X		prl(x-1,y);
X		prl(x,y);
X		prl(x+1,y);
X	}
X}
X
Xvoid
Xnose1(x,y)
Xregister int x, y;
X{
X	if(u.dx) {
X		if(u.dy) {
X			nosee(x,u.uy);
X			nosee(x,u.uy-u.dy);
X			nosee(x,y);
X			nosee(u.ux-u.dx,y);
X			nosee(u.ux,y);
X		} else {
X			nosee(x,y-1);
X			nosee(x,y);
X			nosee(x,y+1);
X		}
X	} else {
X		nosee(x-1,y);
X		nosee(x,y);
X		nosee(x+1,y);
X	}
X}
X
Xint
Xvism_at(x,y)
Xregister int x, y;
X{
X	if(x == u.ux && y == u.uy && !Invisible) return(1);
X
X	if(MON_AT(x, y))
X		return(showmon(m_at(x,y)));
X	return(0);
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
X#ifdef NEWSCR
Xvoid
Xpobj(obj)
Xregister struct obj *obj;
X{
X	register int show = (!obj->oinvis || See_invisible) &&
X		cansee(obj->ox,obj->oy);
X	if(obj->odispl){
X		if(obj->odx != obj->ox || obj->ody != obj->oy || !show)
X		if(!vism_at(obj->odx,obj->ody)){
X			newsym(obj->odx, obj->ody);
X			obj->odispl = 0;
X		}
X	}
X	if(show && !vism_at(obj->ox,obj->oy)){
X		atl(obj->ox,obj->oy,obj->olet);
X		obj->odispl = 1;
X		obj->odx = obj->ox;
X		obj->ody = obj->oy;
X	}
X}
X#endif /* NEWSCR /**/
X
Xvoid
Xunpobj(obj)
Xregister struct obj *obj;
X{
X/* 	if(obj->odispl){
X		if(!vism_at(obj->odx, obj->ody))
X			newsym(obj->odx, obj->ody);
X		obj->odispl = 0;
X	}
X*/
X	if(!vism_at(obj->ox,obj->oy))
X		newsym(obj->ox,obj->oy);
X}
X
X#ifdef WORM
XSTATIC_OVL void
Xpwseg(wtmp)
Xregister struct wseg *wtmp;
X{
X	if(!wtmp->wdispl){
X		atl(wtmp->wx, wtmp->wy, S_WORM_TAIL);
X		wtmp->wdispl = 1;
X	}
X}
X#endif
X
X
X#ifdef STUPID_CPP	/* otherwise these functions are macros in rm.h */
Xboolean IS_WALL(typ)
Xunsigned typ;
X{
X	return(typ && typ <= TRWALL);
X}
X
Xboolean IS_STWALL(typ)
Xunsigned typ;
X{
X	return(typ <= TRWALL);			/* STONE <= (typ) <= TRWALL */
X}
X
Xboolean IS_ROCK(typ)
Xunsigned typ;
X{
X	return(typ < POOL);			/* absolutely nonaccessible */
X}
X
Xboolean IS_DOOR(typ)
Xunsigned typ;
X{
X	return(typ == DOOR);
X}
X
Xboolean ACCESSIBLE(typ)
Xunsigned typ;
X{
X	return(typ >= DOOR);			/* good position */
X}
X
Xboolean IS_ROOM(typ)
Xunsigned typ;
X{
X	return(typ >= ROOM);			/* ROOM, STAIRS, furniture.. */
X}
X
Xboolean ZAP_POS(typ)
Xunsigned typ;
X{
X	return(typ >= POOL);
X}
X
Xboolean SPACE_POS(typ)
Xunsigned typ;
X{
X	return(typ > DOOR);
X}
X
Xboolean IS_POOL(typ)
Xunsigned typ;
X{
X	return(typ >= POOL && typ <= DRAWBRIDGE_UP);
X}
X
Xboolean IS_THRONE(typ)
Xunsigned typ;
X{
X	return(typ == THRONE);
X}
X
Xboolean IS_FOUNTAIN(typ)
Xunsigned typ;
X{
X	return(typ == FOUNTAIN);
X}
X
Xboolean IS_SINK(typ)
Xunsigned typ;
X{
X	return(typ == SINK);
X}
X
Xboolean IS_ALTAR(typ)
Xunsigned typ;
X{
X	return(typ == ALTAR);
X}
X
Xboolean IS_DRAWBRIDGE(typ)
Xunsigned typ;
X{
X	return(typ == DRAWBRIDGE_UP || typ == DRAWBRIDGE_DOWN);
X}
X
Xboolean IS_FURNITURE(typ)
Xunsigned typ;
X{
X	return(typ >= STAIRS && typ <= ALTAR);
X}
X#endif /* STUPID_CPP */
X
X#endif /* OVLB */
END_OF_FILE
if test 12560 -ne `wc -c <'src/prisym.c'`; then
    echo shar: \"'src/prisym.c'\" unpacked with wrong size!
fi
# end of 'src/prisym.c'
fi
if test -f 'src/trap.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/trap.c'\"
else
echo shar: Extracting \"'src/trap.c'\" \(42990 characters\)
sed "s/^X//" >'src/trap.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)trap.c	3.0	89/11/20
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include	"hack.h"
X#include	"edog.h"
X
X#ifdef OVLB
X
Xconst char *traps[] = {
X	"",
X	" monster trap",
X	" statue trap",
X	" bear trap",
X	"n arrow trap",
X	" dart trap",
X	" trapdoor",
X	" teleportation trap",
X	" pit",
X	" sleeping gas trap"
X	," magic trap"
X	," squeaky board"
X	," web"
X	," spiked pit"
X	," level teleporter"
X#ifdef SPELLS
X	,"n anti-magic field" 
X#endif
X	," rust trap"
X#ifdef POLYSELF
X	," polymorph trap"
X#endif
X	," land mine"
X};
X
X#endif /* OVLB */
X
Xvoid NDECL(domagictrap);
XSTATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int));
X
X#ifdef OVLB
X
Xstatic void NDECL(vtele);
X
X/* Generic rust-armor function.  Returns TRUE if a message was printed;
X * "print", if set, means to print a message (and thus to return TRUE) even
X * if the item could not be rusted; otherwise a message is printed and TRUE is
X * returned only for rustable items.
X */
Xboolean
Xrust_dmg(otmp, ostr, type, print)
Xregister struct obj *otmp;
Xregister const char *ostr;
Xint type;
Xboolean print;
X{
X	static const char NEARDATA *gook[] = { "slag", "rust", "rot", "corrosion" };
X	static const char NEARDATA *action[] = { "smolder", "rust", "rot", "corrode" };
X	static const char NEARDATA *msg[] =  { "burnt", "rusted", "rotten", "corroded" };
X	boolean vulnerable = FALSE;
X	boolean plural;
X
X	if (!otmp) return(FALSE);
X	switch(type) {
X		case 0:
X		case 2: vulnerable = is_flammable(otmp); break;
X		case 1: vulnerable = is_rustprone(otmp); break;
X		case 3: vulnerable = is_corrodeable(otmp); break;
X	}
X
X	if (!print && (!vulnerable || otmp->rustfree || otmp->spe < -2))
X		return FALSE;
X
X	plural = is_gloves(otmp) || is_boots(otmp);
X
X	if (!vulnerable)
X		Your("%s %s not affected!", ostr, plural ? "are" : "is");
X	else if (otmp->spe >= -2) {
X		if (otmp->rustfree)
X			pline("The %s on your %s vanishes instantly!",
X						gook[type], ostr);
X		else if (otmp->blessed && !rnl(4))
X			pline("Somehow, your %s %s not affected!", ostr,
X					plural ? "are" : "is");
X		else {
X			Your("%s %s%s!", ostr, action[type],
X				plural ? "" : "s");
X			otmp->spe--;
X			adj_abon(otmp, -1);
X		}
X	} else Your("%s %s%s quite %s.", ostr, Blind ? "feel" : "look",
X					     plural ? "" : "s", msg[type]);
X	return(TRUE);
X}
X
Xstruct trap *
Xmaketrap(x,y,typ)
Xregister int x, y, typ;
X{
X	register struct trap *ttmp;
X	register struct permonst *ptr;
X
X	if (ttmp = t_at(x,y)) {
X		if (u.utrap &&
X		  ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) ||
X		  (u.utraptype == TT_WEB && typ != WEB) ||
X		  (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT)))
X			u.utrap = 0;
X		ttmp->ttyp = typ;
X		return ttmp;
X	}
X	ttmp = newtrap();
X	ttmp->ttyp = typ;
X	ttmp->tx = x;
X	ttmp->ty = y;
X	switch(typ) {
X	    case MONST_TRAP:	    /* create a monster in "hiding" */
X	    {	int tryct = 0;
X		if(rn2(5) && (ptr = mkclass(S_PIERCER)))
X			ttmp->pm = monsndx(ptr);
X		else do {
X			ttmp->pm = rndmonnum();
X		} while ((noattacks(&mons[ttmp->pm]) ||
X			!mons[ttmp->pm].mmove) && ++tryct < 100);
X		if (tryct == 100) {
X			free((genericptr_t)ttmp);
X			return(struct trap *)0;
X		}
X		break;
X	    }
X	    case STATUE_TRAP:	    /* create a "living" statue */
X		ttmp->pm = rndmonnum();
X		(void) mkcorpstat(STATUE, &mons[ttmp->pm], x, y);
X		break;
X	    default:
X		ttmp->pm = -1;
X		break;
X	}
X	ttmp->tseen = 0;
X	ttmp->once = 0;
X	ttmp->ntrap = ftrap;
X	ftrap = ttmp;
X	return(ttmp);
X}
X
Xint
Xteleok(x, y)
Xregister int x, y;
X{				/* might throw him into a POOL
X				 * removed by GAN 10/20/86
X				 */
X#ifdef STUPID
X	boolean	tmp1, tmp2, tmp3;
X#  ifdef POLYSELF
X	tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) ||
X		passes_walls(uasmon)) && !MON_AT(x, y);
X#  else
X	tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !MON_AT(x, y);
X#  endif
X	tmp2 = !sobj_at(BOULDER,x,y) && !t_at(x,y);
X	tmp3 = !(is_pool(x,y) &&
X	       !(Levitation || Wwalking
X#ifdef POLYSELF
X		 || is_flyer(uasmon)
X#endif
X		)) && !closed_door(x,y);
X	return(tmp1 && tmp2 && tmp3);
X#else
X	return( isok(x,y) &&
X#  ifdef POLYSELF
X		(!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) &&
X#  else
X		!IS_ROCK(levl[x][y].typ) &&
X#  endif
X		!MON_AT(x, y) &&
X		!sobj_at(BOULDER,x,y) && !t_at(x,y) &&
X		!(is_pool(x,y) &&
X		!(Levitation || Wwalking
X#ifdef POLYSELF
X		  || is_flyer(uasmon)
X#endif
X		  )) && !closed_door(x,y));
X#endif
X	/* Note: gold is permitted (because of vaults) */
X}
X
Xstatic void
Xvtele() {
X	register struct mkroom *croom;
X
X	for(croom = &rooms[0]; croom->hx >= 0; croom++)
X	    if(croom->rtype == VAULT) {
X		register int x, y;
X
X		x = rn2(2) ? croom->lx : croom->hx;
X		y = rn2(2) ? croom->ly : croom->hy;
X		if(teleok(x,y)) {
X		    teleds(x,y);
X		    return;
X		}
X	    }
X	tele();
X}
X
Xvoid
Xfall_through(td)
Xboolean td;	/* td == TRUE : trapdoor */
X{
X	register int newlevel = dlevel + 1;
X
X	while(!rn2(4) && newlevel < 29) newlevel++;
X	if(td) pline("A trap door opens up under you!");
X	else pline("The floor opens up under you!");
X	if(Levitation || u.ustuck || dlevel == MAXLEVEL
X#ifdef POLYSELF
X		|| is_flyer(uasmon) || u.umonnum == PM_WUMPUS
X#endif
X#ifdef ENDGAME
X		|| dlevel == ENDLEVEL
X#endif
X	) {
X	    You("don't fall in.");
X	    if(!td) {
X		more();
X		pline("The opening under you closes up.");
X	    }
X	    return;
X	}
X#ifdef WALKIES
X	if(!next_to_u()) {
X	    You("are jerked back by your pet!");
X	    if(!td) {
X		more();
X		pline("The opening in the floor closes up.");
X	    }
X	} else {
X#endif
X	    if(in_shop(u.ux, u.uy)) shopdig(1);
X	    unsee();
X	    (void) fflush(stdout);
X	    goto_level(newlevel, FALSE, TRUE);
X	    if(!td) pline("The hole in the ceiling above you closes up.");
X#ifdef WALKIES
X	}
X#endif
X}
X
Xvoid
Xdotrap(trap)
Xregister struct trap *trap;
X{
X	register int ttype = trap->ttyp;
X	register struct monst *mtmp;
X	register struct obj *otmp;
X
X	nomul(0);
X	if(trap->tseen && !Fumbling && !(ttype == PIT
X	   || ttype == SPIKED_PIT
X#ifdef SPELLS
X	   || ttype == ANTI_MAGIC
X#endif
X		) && !rn2(5))
X		You("escape a%s.", traps[ttype]);
X	else {
X	    trap->tseen = 1;
X	    if(Invisible && ttype != MONST_TRAP)
X		newsym(trap->tx,trap->ty);
X	    switch(ttype) {
X		case SLP_GAS_TRAP:
X		    if(Sleep_resistance) {
X			You("are enveloped in a cloud of gas!");
X			break;
X		    }
X		    pline("A cloud of gas puts you to sleep!");
X		    flags.soundok = 0;
X		    nomul(-rnd(25));
X		    afternmv = Hear_again;
X		    break;
X		case BEAR_TRAP:
X		    if(Levitation
X#ifdef POLYSELF
X				|| is_flyer(uasmon)) {
X			You("%s over a bear trap.",
X			      Levitation ? "float" : "fly");
X#else
X				) {
X			You("float over a bear trap.");
X#endif
X			break;
X		    }
X#ifdef POLYSELF
X		    if(amorphous(uasmon)) {
X			pline("A bear trap closes harmlessly through you.");
X			break;
X		    }
X#endif
X		    u.utrap = 4 + rn2(4);
X		    u.utraptype = TT_BEARTRAP;
X		    pline("A bear trap closes on your %s!",
X			body_part(FOOT));
X#ifdef POLYSELF
X		    if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
X			You("howl in anger!");
X#endif
X		    break;
X		case STATUE_TRAP:
X		    deltrap(trap);
X		    for(otmp=level.objects[u.ux][u.uy];
X						otmp; otmp = otmp->nexthere)
X			if(otmp->otyp == STATUE && otmp->corpsenm == trap->pm)
X			    if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) {
X				pline("The statue comes to life!");
X				delobj(otmp);
X				break;
X			    }
X		    break;
X		case MONST_TRAP:
X		    if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) {
X		      mtmp->mpeaceful = FALSE;
X		      switch(mtmp->data->mlet) {
X			case S_PIERCER:
X			    pline("%s suddenly drops from the ceiling!",
X				  Xmonnam(mtmp));
X			    if(uarmh)
X				pline("Its blow glances off your helmet.");
X			    else
X				(void) thitu(3,d(4,6),(struct obj *)0,
X					"falling piercer");
X			    break;
X			default:	/* monster surprises you. */
X			    pline("%s attacks you by surprise!",
X				  Xmonnam(mtmp));
X			    break;
X		      }
X		    }
X		    deltrap(trap);
X		    break;
X		case ARROW_TRAP:
X		    pline("An arrow shoots out at you!");
X		    if(!thitu(8,rnd(6),(struct obj *)0,"arrow")){
X			(void) mksobj_at(ARROW, u.ux, u.uy);
X			fobj->quan = 1;
X			fobj->owt = weight(fobj);
X		    }
X		    break;
X		case TRAPDOOR:
X		    if(is_maze_lev
X#ifdef STRONGHOLD
X			 && (dlevel > stronghold_level)
X#endif
X		      ) {
X	pline("A trap door in the ceiling opens and a rock falls on your %s!",
X				body_part(HEAD));
X			if(uarmh)
X			    pline("Fortunately, you are wearing a helmet!");
X			losehp(uarmh ? 2 : d(2,10),"falling rock", KILLED_BY_AN);
X			(void) mksobj_at(ROCK, u.ux, u.uy);
X			fobj->quan = 1;
X			fobj->owt = weight(fobj);
X			stackobj(fobj);
X			if(Invisible
X#ifdef POLYSELF
X				|| u.uundetected
X#endif
X						) newsym(u.ux, u.uy);
X		    } else fall_through(TRUE);
X		    break;
X		case DART_TRAP:
X		    pline("A little dart shoots out at you!");
X		    if(thitu(7,rnd(3),(struct obj *)0,"little dart")) {
X			if(!rn2(6)) poisoned("dart",A_CON,"poison dart",10);
X		    } else {
X			(void) mksobj_at(DART, u.ux, u.uy);
X			fobj->quan = 1;
X			if(!rn2(6)) fobj->opoisoned = 1;
X			fobj->owt = weight(fobj);
X		    }
X		    break;
X		case TELEP_TRAP:
X		    if(trap->once) {
X#ifdef ENDGAME
X			if(dlevel == ENDLEVEL) {
X			    You("feel a wrenching sensation.");
X			    break;
X			}
X#endif
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    You("feel a wrenching sensation.");
X			} else {
X			    deltrap(trap);
X			    newsym(u.ux, u.uy);
X			    vtele();
X			}
X		    } else {
X#ifdef ENDGAME
X			if(dlevel == ENDLEVEL) {
X			    You("feel a wrenching sensation.");
X			    break;
X			}
X#endif
X			if(Antimagic) {
X			    shieldeff(u.ux, u.uy);
X			    You("feel a wrenching sensation.");
X			} else {
X			    newsym(u.ux, u.uy);
X			    tele();
X			}
X		    }
X		    break;
X		case RUST_TRAP:
X#ifdef POLYSELF
X# ifdef GOLEMS
X		    if (u.umonnum == PM_IRON_GOLEM) {
X			pline("A gush of water hits you!");
X			You("are covered with rust!");
X			rehumanize();
X			break;
X		    } else
X# endif /* GOLEMS */
X		    if (u.umonnum == PM_GREMLIN && rn2(3)) {
X			pline("A gush of water hits you!");
X			if(mtmp = cloneu()) {
X			    mtmp->mhpmax = (u.mhmax /= 2);
X			    You("multiply.");
X			}
X			break;
X		    }
X#endif
X		/* Unlike monsters, traps cannot aim their rust attacks at
X		 * you, so instead of looping through and taking either the
X		 * first rustable one or the body, we take whatever we get,
X		 * even if it is not rustable.
X		 */
X		    switch (rn2(5)) {
X			case 0:
X			    pline("A gush of water hits you on the %s!",
X					body_part(HEAD));
X			    (void) rust_dmg(uarmh, "helmet", 1, TRUE);
X			    break;
X			case 1:
X			    pline("A gush of water hits your left %s!",
X					body_part(ARM));
X			    if (rust_dmg(uarms, "shield", 1, TRUE)) break;
X			    if (uwep && bimanual(uwep))
X				goto two_hand;
X			    /* Two goto statements in a row--aaarrrgggh! */
Xglovecheck:		    (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
X			    /* Not "metal gauntlets" since it gets called
X			     * even if it's leather for the message
X			     */
X			    break;
X			case 2:
X			    pline("A gush of water hits your right %s!",
X					body_part(ARM));
Xtwo_hand:		    corrode_weapon();
X			    goto glovecheck;
X			default:
X			    pline("A gush of water hits you!");
X			    if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE);
X			    else if (uarm)
X				(void) rust_dmg(uarm, "armor", 1, TRUE);
X#ifdef SHIRT
X			    else if (uarmu)
X				(void) rust_dmg(uarmu, "shirt", 1, TRUE);
X#endif
X		    }
X		    break;
X		case PIT:
X		    if (Levitation
X#ifdef POLYSELF
X			|| is_flyer(uasmon) || u.umonnum == PM_WUMPUS
X#endif
X			) {
X			pline("A pit opens up under you!");
X			You("don't fall in!");
X			break;
X		    }
X		    You("fall into a pit!");
X#ifdef POLYSELF
X		    if (!passes_walls(uasmon))
X#endif
X			u.utrap = rn1(6,2);
X		    u.utraptype = TT_PIT;
X		    losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX);
X		    selftouch("Falling, you");
X		    break;
X		case SPIKED_PIT:
X		    if (Levitation
X#ifdef POLYSELF
X			|| is_flyer(uasmon) || u.umonnum == PM_WUMPUS
X#endif
X			) {
X			pline("A pit full of spikes opens up under you!");
X			You("don't fall in!");
X			break;
X		    }
X		    You("fall into a pit!");
X		    You("land on a set of sharp iron spikes!");
X#ifdef POLYSELF
X		    if (!passes_walls(uasmon))
X#endif
X			u.utrap = rn1(6,2);
X		    u.utraptype = TT_PIT;
X		    losehp(rnd(10),"fell into a pit of iron spikes",
X			NO_KILLER_PREFIX);
X		    if(!rn2(6)) poisoned("spikes",A_STR,"fall onto poison spikes",8);
X		    selftouch("Falling, you");
X		    break;
X		case LEVEL_TELEP:
X
X		    {	int oldl = dlevel;
X
X		    You("%s onto a level teleport trap!",
X			  Levitation ? "float" :
X#ifdef POLYSELF
X			  locomotion(uasmon, "step"));
X#else
X			  "step");
X#endif
X		    if(Antimagic) {
X			pru();
X			shieldeff(u.ux, u.uy);
X		    }
X		    if(Antimagic
X#ifdef ENDGAME
X				|| dlevel == ENDLEVEL
X#endif
X							) {
X			You("feel a wrenching sensation.");
X			break;
X		    }
X		    if(!Blind)
X		      You("are momentarily blinded by a flash of light.");
X		    else
X			You("are momentarily disoriented.");
X		    deltrap(trap);
X		    newsym(u.ux,u.uy);
X		    level_tele();
X		    if(oldl == dlevel && !Invisible
X#ifdef POLYSELF
X						&& !u.uundetected
X#endif
X								) {
X			levl[u.ux][u.uy].seen = 0; /* force atl */
X			atl(u.ux,u.uy,(char)u.usym);
X		    }
X		}
X		    break;
X#ifdef SPELLS
X		case ANTI_MAGIC:
X		    if(Antimagic) {
X			shieldeff(u.ux, u.uy);
X			You("feel momentarily lethargic.");
X		    } else drain_en(rnd((int)u.ulevel) + 1);
X		    break;
X#endif
X#ifdef POLYSELF
X		case POLY_TRAP:
X		    if(Antimagic) {
X			shieldeff(u.ux, u.uy);
X			You("feel momentarily different.");
X			/* Trap did nothing; don't remove it --KAA */
X		    } else {
X			You("feel a change coming over you.");
X			polyself();
X			deltrap(trap);
X		    }
X		    break;
X#endif
X		case MGTRP:	    /* A magic trap. */
X		    if (!rn2(30)) {
X			You("are caught in a magical explosion!");
X			losehp(rnd(10), "magical explosion", KILLED_BY_AN);
X#ifdef SPELLS
X			Your("body absorbs some of the magical energy!");
X			u.uen = (u.uenmax += 2);
X#endif
X			deltrap(trap);
X			if(Invisible
X#ifdef POLYSELF
X				&& !u.uundetected
X#endif
X						) newsym(u.ux,u.uy);
X		    } else domagictrap();
X		    break;
X		case SQBRD:	    /* stepped on a squeaky board */
X		    if (Levitation
X#ifdef POLYSELF
X			|| is_flyer(uasmon)
X#endif
X			) {
X			if (Hallucination) You("notice a crease in the linoleum.");
X			else You("notice a loose board below you.");
X		    } else {
X			pline("A board beneath you squeaks loudly.");
X			wake_nearby();
X		    }
X		    break;
X		case WEB: /* Our luckless player has stumbled into a web. */
X
X		    You("%s into a spider web!",
X			  Levitation ? "float" :
X#ifdef POLYSELF
X			  locomotion(uasmon, "stumble"));
X#else
X			  "stumble");
X#endif
X		    u.utraptype = TT_WEB;
X
X		    /* Time stuck in the web depends on your strength. */
X
X		    if (ACURR(A_STR) == 3) u.utrap = rn1(6,6);
X		    else if (ACURR(A_STR) < 6) u.utrap = rn1(6,4);
X		    else if (ACURR(A_STR) < 9) u.utrap = rn1(4,4);
X		    else if (ACURR(A_STR) < 12) u.utrap = rn1(4,2);
X		    else if (ACURR(A_STR) < 15) u.utrap = rn1(2,2);
X		    else if (ACURR(A_STR) < 18) u.utrap = rnd(2);
X		    else if (ACURR(A_STR) < 69) u.utrap = 1;
X		    else {
X			u.utrap = 0;
X			You("tear through the web!");
X			deltrap(trap);
X	   		if(Invisible) newsym(u.ux,u.uy);
X		    }
X		    break;
X
X		case LANDMINE: {
X#ifndef LINT
X		    register struct monst *mtmp = fmon;
X#endif
X
X		    if (Levitation
X#ifdef POLYSELF
X					|| is_flyer(uasmon)
X#endif
X								) {
X			You("see a trigger in a pile of soil below you.");
X			if (rn2(3)) break;
X			pline("KAABLAMM!!!  The air currents set it off!");
X		    } else {
X			pline("KAABLAMM!!!  You triggered a land mine!");
X			set_wounded_legs(LEFT_SIDE, 40 + rnd(35));
X			set_wounded_legs(RIGHT_SIDE, 40 + rnd(35));
X		    }
X		    losehp(rnd(16), "land mine", KILLED_BY_AN);
X		    /* wake everything on the level */
X		    while(mtmp) {
X			if(mtmp->msleep) mtmp->msleep = 0;
X			mtmp = mtmp->nmon;
X		    }
X		    deltrap(t_at(u.ux, u.uy)); /* mines only explode once */
X		    if(Invisible) newsym(u.ux,u.uy);
X		    }
X		    break;
X		default:
X		    impossible("You hit a trap of type %u", trap->ttyp);
X	    }
X	}
X}
X
X#endif /* OVLB */
X
X#ifdef WALKIES
X
XSTATIC_DCL boolean FDECL(teleport_pet, (struct monst *));
X
X#ifdef OVLB
X
XSTATIC_OVL boolean
Xteleport_pet(mtmp)
Xregister struct monst *mtmp;
X{
X	register struct obj *otmp;
X
X	if(mtmp->mleashed) {
X	    otmp = get_mleash(mtmp);
X	    if(!otmp)
X		impossible("%s is leashed, without a leash.", Monnam(mtmp));
X	    if(otmp->cursed) {
X# ifdef SOUNDS
X		yelp(mtmp);
X# endif
X		return FALSE;
X	    } else {
X		Your("leash goes slack.");
X		m_unleash(mtmp);
X		return TRUE;
X	    }
X	}
X	return TRUE;
X}
X
X#endif /* OVLB */
X
X#endif /* WALKIES */
X
XSTATIC_DCL void FDECL(seetrap, (struct trap *));
X
X#ifdef OVLB
X
XSTATIC_OVL void
Xseetrap(trap)
X
X	register struct trap *trap;
X{
X	if(!trap->tseen) {
X
X	    trap->tseen = 1;
X	    newsym(trap->tx, trap->ty);
X	}
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xint
Xmintrap(mtmp)
Xregister struct monst *mtmp;
X{
X	register struct trap *trap = t_at(mtmp->mx, mtmp->my);
X	register int newlev, wasintrap = mtmp->mtrapped;
X	register boolean trapkilled = FALSE, tdoor = FALSE;
X	struct obj *otmp;
X
X	if(!trap) {
X		mtmp->mtrapped = 0;	/* perhaps teleported? */
X	} else if(wasintrap) {
X		if(!rn2(40)) mtmp->mtrapped = 0;
X	} else {
X	    register int tt = trap->ttyp;
X
X	/* A bug fix for dumb messages by ab@unido.
X	 */
X	    int in_sight = cansee(mtmp->mx,mtmp->my)
X			   && (!mtmp->minvis || See_invisible);
X
X	    if(mtmp->mtrapseen & (1 << tt)) {
X		/* he has been in such a trap - perhaps he escapes */
X		if(rn2(4)) return(0);
X	    }
X	    mtmp->mtrapseen |= (1 << tt);
X	    switch (tt) {
X		case BEAR_TRAP:
X			if(mtmp->data->msize > MZ_SMALL &&
X			   !amorphous(mtmp->data)) {
X				mtmp->mtrapped = 1;
X				if(in_sight) {
X				  pline("%s is caught in a bear trap!",
X					Monnam(mtmp));
X				  seetrap(trap);
X				} else
X				    if((mtmp->data == &mons[PM_OWLBEAR]
X					|| mtmp->data == &mons[PM_BUGBEAR])
X					&& flags.soundok)
X			    You("hear the roaring of an angry bear!");
X			}
X			break;
X#ifdef POLYSELF
X		case POLY_TRAP:
X		    if(!resist(mtmp, WAND_SYM, 0, NOTELL)) {
X			(void) newcham(mtmp, (struct permonst *)0);
X			seetrap(trap);
X		    }
X		    break;
X#endif
X		case RUST_TRAP:
X			if(in_sight)
X			    pline("A gush of water hits %s!", mon_nam(mtmp));
X			if(cansee(mtmp->mx,mtmp->my))
X			    seetrap(trap);
X#ifdef GOLEMS
X			if (mtmp->data == &mons[PM_IRON_GOLEM]) {
X				if (in_sight)
X				    pline("%s falls to pieces!", Monnam(mtmp));
X				else if(mtmp->mtame)
X				    pline("May %s rust in peace.",
X								mon_nam(mtmp));
X				mondied(mtmp);
X				trapkilled = TRUE;
X			} else
X#endif /* GOLEMS */
X			if (mtmp->data == &mons[PM_GREMLIN] && rn2(3)) {
X				struct monst *mtmp2 = clone_mon(mtmp);
X
X				if (mtmp2) {
X				    mtmp2->mhpmax = (mtmp->mhpmax /= 2);
X				    if(in_sight)
X					pline("%s multiplies.", Monnam(mtmp));
X				}
X			}
X			break;
X		case PIT:
X		case SPIKED_PIT:
X			/* TO DO: there should be a mtmp/data -> floating */
X			if(!is_flyer(mtmp->data) &&
X			   mtmp->data != &mons[PM_WUMPUS]) {
X				if (!passes_walls(mtmp->data))
X				    mtmp->mtrapped = 1;
X				if(in_sight) {
X				    pline("%s falls into a pit!", Monnam(mtmp));
X				    seetrap(trap);
X				}
X				if(thitm(0, mtmp, (struct obj *)0,
X					 rnd((tt==PIT) ? 6 : 10)))
X				    trapkilled = TRUE;
X			}
X			break;
X		case SLP_GAS_TRAP:
X			if(!resists_sleep(mtmp->data) &&
X			   !mtmp->msleep && mtmp->mcanmove) {
X				mtmp->mcanmove = 0;
X				mtmp->mfrozen = rnd(25);
X				if(in_sight)
X				  pline("%s suddenly falls asleep!",
X					Monnam(mtmp));
X				if(cansee(mtmp->mx,mtmp->my))
X				    seetrap(trap);
X			}
X			break;
X		case TELEP_TRAP:
X#ifdef WALKIES
X			if(teleport_pet(mtmp)) {
X#endif
X			    /* Note: don't remove the trap if a vault.  Other-
X			     * the monster will be stuck there, since the guard
X			     * isn't going to come for it...
X			     */
X			    if (trap->once) vloc(mtmp);
X			    else rloc(mtmp);
X			    if(in_sight && !cansee(mtmp->mx,mtmp->my)) {
X				pline("%s suddenly disappears!",
X					Monnam(mtmp));
X				seetrap(trap);
X			    }
X#ifdef WALKIES
X			}
X#endif
X			break;
X		case ARROW_TRAP:
X			otmp = mksobj(ARROW, FALSE);
X			otmp->quan = 1;
X			otmp->owt = weight(otmp);
X			if(in_sight) seetrap(trap);
X			if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE;
X			break;
X		case DART_TRAP:
X			otmp = mksobj(DART, FALSE);
X			otmp->quan = 1;
X			if (!rn2(6)) otmp->opoisoned = 1;
X			otmp->owt = weight(otmp);
X			if(in_sight) seetrap(trap);
X			if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE;
X			break;
X		case TRAPDOOR:
X			if(is_maze_lev
X#ifdef STRONGHOLD
X			   && (dlevel > stronghold_level && dlevel < MAXLEVEL)
X#endif
X			  ) {
X				otmp = mksobj(ROCK, FALSE);
X				otmp->quan = 1;
X				otmp->owt = weight(otmp);
X				if(in_sight) seetrap(trap);
X				if(thitm(0, mtmp, otmp, d(2, 10)))
X					trapkilled = TRUE;
X				break;
X			}
X			if (mtmp->data == &mons[PM_WUMPUS]) break;
X			tdoor = TRUE;
X			/* Fall through */
X		case LEVEL_TELEP:
X			if(!is_flyer(mtmp->data)
X#ifdef WORM
X				&& !mtmp->wormno
X			    /* long worms with tails mustn't change levels */
X#endif
X			    ) {
X#ifdef WALKIES
X			    if(teleport_pet(mtmp)) {
X#endif
X				if(tdoor)
X				    fall_down(mtmp, dlevel+1);
X				else {
X				    newlev = rnd(3);
X				    if(!rn2(2)) newlev = -(newlev);
X				    newlev = dlevel + newlev;
X				    if(newlev > MAXLEVEL) {
X					if(dlevel != MAXLEVEL)
X					    newlev = MAXLEVEL;
X					else newlev = MAXLEVEL - rnd(3);
X				    }
X				    if(newlev < 1) {
X					if(dlevel != 1) newlev = 1;
X					else newlev = 1 + rnd(3);
X				    }
X				    fall_down(mtmp, newlev);
X				}
X				if(in_sight) {
X		pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
X				    seetrap(trap);
X				}
X				return(2);	/* no longer on this level */
X#ifdef WALKIES
X			    }
X#endif
X			}
X			break;
X		case MONST_TRAP:
X		case STATUE_TRAP:
X			break;
X		case MGTRP:
X			/* A magic trap.  Monsters immune. */
X			break;
X		case SQBRD: {
X			register struct monst *ztmp = fmon;
X
X			if(is_flyer(mtmp->data)) break;
X			/* stepped on a squeaky board */
X			if (in_sight) {
X			    pline("A board beneath %s squeaks loudly.", mon_nam(mtmp));
X			    seetrap(trap);
X			} else
X			   You("hear a distant squeak.");
X			/* wake up nearby monsters */
X			while(ztmp) {
X			    if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
X				if(ztmp->msleep) ztmp->msleep = 0;
X			    ztmp = ztmp->nmon;
X			}
X			break;
X		}
X	       case WEB:
X			/* Monster in a web. */
X			if(mtmp->data->mlet != S_SPIDER) {
X			    if(in_sight)
X				pline("%s is caught in a web.", Monnam(mtmp));
X			    else /* Eric Backus */
X				if(mtmp->data == &mons[PM_OWLBEAR] ||
X					mtmp->data == &mons[PM_BUGBEAR])
X				    You("hear the roaring of a confused bear!");
X			    mtmp->mtrapped = 1;
X			}
X			break;
X#ifdef SPELLS
X		case ANTI_MAGIC:	break;
X#endif
X		case LANDMINE: {
X			register struct monst *mntmp = fmon;
X
X			if(rn2(3))
X				break; /* monsters usually don't set it off */
X			if(is_flyer(mtmp->data)) {
X				if (in_sight) {
X	pline("A trigger appears in a pile of soil below %s.", Monnam(mtmp));
X					seetrap(trap);
X				}
X				if (rn2(3)) break;
X				if (in_sight)
X					pline("The air currents set it off!");
X			} else if(in_sight)
X			    pline("KAABLAMM!!!  %s triggers a land mine!",
X				  Monnam(mtmp));
X			if (!in_sight && flags.soundok)
X				pline("Kaablamm!  You hear an explosion in the distance!");
X			deltrap(t_at(mtmp->mx, mtmp->my));
X			if(thitm(0, mtmp, (struct obj *)0, rnd(16)))
X				trapkilled = TRUE;
X			/* wake everything on the level */
X			while(mntmp) {
X				if(mntmp->msleep)
X					mntmp->msleep = 0;
X				mntmp = mntmp->nmon;
X			}
X			break;
X		}
X		default:
X			impossible("Some monster encountered a strange trap of type %d.", tt);
X	    }
X	}
X	if(trapkilled) return 2;
X	else return mtmp->mtrapped;
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xvoid
Xselftouch(arg)
Xconst char *arg;
X{
X	if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE)
X#ifdef POLYSELF
X			&& !resists_ston(uasmon)
X#endif
X	){
X		pline("%s touch the cockatrice corpse.", arg);
X		You("turn to stone...");
X		killer_format = KILLED_BY;
X		killer = "touching a cockatrice corpse";
X		done(STONING);
X	}
X}
X
Xvoid
Xfloat_up() {
X	if(u.utrap) {
X		if(u.utraptype == TT_PIT) {
X			u.utrap = 0;
X			You("float up, out of the pit!");
X		} else {
X			You("float up, only your %s is still stuck.",
X				body_part(LEG));
X		}
X	} else
X		if (Hallucination)
X			pline("Up, up, and awaaaay!  You're walking on air!");
X		else
X			You("start to float in the air!");
X}
X
Xint
Xfloat_down() {
X	register struct trap *trap;
X
X	if(Levitation) return(0); /* maybe another ring/potion/boots */
X
X	/* check for falling into pool - added by GAN 10/20/86 */
X	if(is_pool(u.ux,u.uy) && !(Wwalking
X#ifdef POLYSELF
X				    || is_flyer(uasmon)
X#endif
X				    ))
X		drown();
X
X	You("float gently to the ground.");
X	if(trap = t_at(u.ux,u.uy))
X		switch(trap->ttyp) {
X		case MONST_TRAP:
X		case STATUE_TRAP:
X			break;
X		case TRAPDOOR:
X			if(is_maze_lev
X#ifdef STRONGHOLD
X			   && (dlevel >= stronghold_level || dlevel < MAXLEVEL)
X#endif
X			   || u.ustuck) break;
X			/* fall into next case */
X		default:
X			dotrap(trap);
X	}
X	if(!flags.nopick && (OBJ_AT(u.ux, u.uy) || levl[u.ux][u.uy].gmask))
X	    pickup(1);
X	return 0;
X}
X
X
Xvoid
Xtele() {
X	coord cc;
X	register int nux,nuy;
X
X#ifdef STRONGHOLD
X	/* Disable teleportation in stronghold && Vlad's Tower */
X	if(dlevel == stronghold_level ||
X# ifdef ENDGAME
X	   dlevel == ENDLEVEL ||
X# endif
X	   (dlevel >= tower_level && dlevel <= tower_level + 2)) {
X# ifdef WIZARD
X		if (!wizard) {
X# endif
X		    pline("A mysterious force prevents you from teleporting!");
X		    return;
X# ifdef WIZARD
X		}
X# endif
X	}
X#endif /* STRONGHOLD /**/
X	if((u.uhave_amulet || dlevel == wiz_level) && !rn2(3)) {
X	    You("feel disoriented for a moment.");
X	    return;
X	}
X	if(Teleport_control) {
X	    if (unconscious())
X		pline("Being unconscious, you cannot control your teleport.");
X	    else {
X		    pline("To what position do you want to be teleported?");
X		    cc.x = u.ux;
X		    cc.y = u.uy;
X		    getpos(&cc, 1, "the desired position"); /* 1: force valid */
X		    /* possible extensions: introduce a small error if
X		       magic power is low; allow transfer to solid rock */
X		    if(teleok(cc.x, cc.y)){
X			teleds(cc.x, cc.y);
X			return;
X		    }
X		    pline("Sorry...");
X		}
X	}
X	do {
X		nux = rnd(COLNO-1);
X		nuy = rn2(ROWNO);
X	} while(!teleok(nux, nuy));
X	teleds(nux, nuy);
X}
X
Xvoid
Xteleds(nux, nuy)
Xregister int nux,nuy;
X{
X	if(Punished) unplacebc();
X	unsee();
X	u.utrap = 0;
X	u.ustuck = 0;
X	u.ux0 = u.ux;
X	u.uy0 = u.uy;
X	u.ux = nux;
X	u.uy = nuy;
X#ifdef POLYSELF
X	if (hides_under(uasmon))
X		u.uundetected = (OBJ_AT(nux, nuy) || levl[nux][nuy].gmask);
X	else 
X		u.uundetected = 0;
X	if (u.usym == S_MIMIC_DEF) u.usym = S_MIMIC;
X#endif
X	if(Punished) placebc(1);
X	if(u.uswallow){
X		u.uswldtim = u.uswallow = 0;
X		docrt();
X	}
X	setsee();
X	nomul(0);
X	spoteffects();
X}
X
Xint
Xdotele()
X{
X	struct trap *trap;
X#ifdef SPELLS
X	boolean castit = FALSE;
X# ifdef __GNULINT__
X	register int sp_no = 0;
X# else
X	register int sp_no;
X# endif
X#endif
X
X	trap = t_at(u.ux, u.uy);
X	if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
X		trap = 0;
X
X	if (trap) {
X		if (trap->once) {
X			pline("This is a vault teleport, usable once only.");
X			pline("Jump in? ");
X			if (yn() == 'n')
X				trap = 0;
X			else {
X				deltrap(trap);
X				newsym(u.ux, u.uy);
X			}
X		}
X		if (trap)
X#ifdef POLYSELF
X			You("%s onto the teleportation trap.",
X			    locomotion(uasmon, "jump"));
X#else
X			You("jump onto the teleportation trap.");
X#endif
X	}
X	if(!trap && (!Teleportation ||
X	   (u.ulevel < (pl_character[0] == 'W' ? 8 : 12)
X#ifdef POLYSELF
X	    && !can_teleport(uasmon)
X#endif
X	   )
X	  )) {
X#ifdef SPELLS
X		/* Try to use teleport away spell. */
X		castit = objects[SPE_TELEPORT_AWAY].oc_name_known;
X		if (castit) {
X		    for (sp_no = 0; sp_no < MAXSPELL &&
X				spl_book[sp_no].sp_id != NO_SPELL &&
X				spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY; sp_no++);
X
X		    if (sp_no == MAXSPELL ||
X			spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY)
X			    castit = FALSE;
X		}
X#endif
X#ifdef WIZARD
X		if (!wizard) {
X#endif
X#ifdef SPELLS
X		    if (!castit) {
X			if (!Teleportation)
X			    You("don't know that spell.");
X			else
X#endif
X			    You("are not able to teleport at will.");
X			return(0);
X#ifdef SPELLS
X		    }
X#endif
X#ifdef WIZARD
X		}
X#endif
X	}
X
X	if(!trap && (u.uhunger <= 100 || ACURR(A_STR) < 6)) {
X		You("lack the strength for a teleport spell.");
X#ifdef WIZARD
X		if(!wizard)
X#endif
X		return(1);
X	}
X
X#ifdef SPELLS
X	if (castit)
X# ifdef WIZARD
X		if (!spelleffects(++sp_no, TRUE) && !wizard) return(0);
X# else
X		return spelleffects(++sp_no, TRUE);
X# endif
X#endif
X
X#ifdef WALKIES
X	if(next_to_u()) {
X#endif
X		if (trap && trap->once) vtele();
X		else tele();
X#ifdef WALKIES
X		(void) next_to_u();
X	} else {
X		You("shudder for a moment.");
X		return(0);
X	}
X#endif
X	if (!trap) morehungry(100);
X	return(1);
X}
X
Xvoid
Xplacebc(attach)
Xint attach;
X{
X	if(!uchain || !uball){
X		impossible("Where are your ball and chain?");
X		return;
X	}
X	if(!carried(uball))
X		place_object(uball, u.ux, u.uy);
X	place_object(uchain, u.ux, u.uy);
X	if(attach){
X		uchain->nobj = fobj;
X		fobj = uchain;
X		if(!carried(uball)){
X			uball->nobj = fobj;
X			fobj = uball;
X		}
X	}
X}
X
Xvoid
Xunplacebc(){
X	if(!carried(uball)){
X		freeobj(uball);
X		unpobj(uball);
X	}
X	freeobj(uchain);
X	unpobj(uchain);
X}
X
Xvoid
Xlevel_tele() {
X	register int newlevel;
X
X	if(u.uhave_amulet
X#ifdef ENDGAME
X		|| dlevel == ENDLEVEL
X#endif
X	) {
X	    You("feel very disoriented for a moment.");
X	    return;
X	}
X	if(Teleport_control
X#ifdef WIZARD
X	   || wizard
X#endif
X		) {
X	    char buf[BUFSZ];
X
X	    do {
X	      pline("To what level do you want to teleport? [type a number] ");
X	      getlin(buf);
X	    } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
X	    newlevel = atoi(buf);
X	} else {
X#ifdef STRONGHOLD
X	    /* We cannot send them to Hell if STRONGHOLD is defined, since
X	     * they may find themselves trapped on the other side of the
X	     * stronghold...
X	     */
X	    newlevel = rn2(5) ? rnd(dlevel + 3) : rnd(stronghold_level);
X#else
X	    newlevel = rn2(5) || !Fire_resistance ? rnd(dlevel + 3) : HELLLEVEL;
X#endif
X	    if(dlevel == newlevel)
X		if(is_maze_lev) newlevel--; else newlevel++;
X	}
X
X#ifdef WALKIES
X	if(!next_to_u()) {
X		You("shudder for a moment...");
X		return;
X	}
X#endif
X
X	if(newlevel < 0) {
X		if(newlevel <= -10) {
X			You("arrive in heaven.");
X			verbalize("Thou art early, but we'll admit thee.");
X			killer_format = NO_KILLER_PREFIX;
X			killer = "went to heaven prematurely";
X			done(DIED);
X			return;
X		} else	if (newlevel == -9) {
X			You("feel deliriously happy. ");
X			pline("(In fact, you're on Cloud 9!) ");
X			more();
X		} else
X			You("are now high above the clouds...");
X
X		if(Levitation) {
X		    You("float gently down to earth.");
X#ifdef STRONGHOLD
X		    newlevel = 1;
X#else
X		    done(ESCAPED);
X#endif
X		}
X#ifdef POLYSELF
X		else if(is_flyer(uasmon)) {
X		    You("fly down to earth.");
X# ifdef STRONGHOLD
X		    newlevel = 1;
X# else
X		    done(ESCAPED);
X# endif
X		}
X#endif
X		else {
X		    int save_dlevel;
X
X		    save_dlevel = dlevel;
X		    pline("Unfortunately, you don't know how to fly.");
X		    You("plummet a few thousand feet to your death.");
X		    dlevel = 0;
X		    killer_format = NO_KILLER_PREFIX;
X		    killer =
X    self_pronoun("teleported out of the dungeon and fell to %s death","his");
X		    done(DIED);
X		    dlevel = save_dlevel;
X		    return;  
X		}
X	}
X
X	/* calls done(ESCAPED) if newlevel==0 */
X	goto_level(newlevel, FALSE, FALSE);
X}
X
Xvoid
Xdomagictrap() {
X	register int fate = rnd(20);
X
X	/* What happened to the poor sucker? */
X
X	if (fate < 10) {
X
X	  /* Most of the time, it creates some monsters. */
X	  register int cnt = rnd(4);
X
X	  /* below checks for blindness added by GAN 10/30/86 */
X	  if (!Blind)  {
X		You("are momentarily blinded by a flash of light!");
X		make_blinded((long)rn1(5,10),FALSE);
X	  }  else
X		You("hear a deafening roar!");
X	  while(cnt--)
X		(void) makemon((struct permonst *) 0, u.ux, u.uy);
X	}
X	else
X	  switch (fate) {
X
X	     case 10:
X	     case 11:
X		      /* sometimes nothing happens */
X			break;
X	     case 12:
X		      /* a flash of fire */
X		      {
X			register int num;
X
X			/* changed to be in conformance with
X			 * SCR_FIRE by GAN 11/02/86
X			 */
X
X			pline("A tower of flame bursts from the floor!");
X			if(Fire_resistance) {
X				shieldeff(u.ux, u.uy);
X				You("are uninjured.");
X				break;
X			} else {
X				num = rnd(6);
X				u.uhpmax -= num;
X				losehp(num,"burst of flame", KILLED_BY_AN);
X				break;
X			}
X		      }
X
X	     /* odd feelings */
X	     case 13:	pline("A shiver runs up and down your %s!",
X			      body_part(SPINE));
X			break;
X	     case 14:	You(Hallucination ?
X				"hear the moon howling at you." :
X				"hear distant howling.");
X			break;
X	     case 15:	You("suddenly yearn for %s.",
X				Hallucination ? "Cleveland" :
X						"your distant homeland");
X			break;
X	     case 16:   Your("pack shakes violently!");
X			break;
X	     case 17:	You(Hallucination ?
X				"smell hamburgers." :
X				"smell charred flesh.");
X			break;
X
X	     /* very occasionally something nice happens. */
X
X	     case 19:
X		    /* tame nearby monsters */
X		   {   register int i,j;
X		       register struct monst *mtmp;
X
X		       /* below pline added by GAN 10/30/86 */
X		       adjattrib(A_CHA,1,FALSE);
X		       for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) {
X			   if(!isok(u.ux+i, u.uy+j)) continue;
X			   mtmp = m_at(u.ux+i, u.uy+j);
X			   if(mtmp)
X			       (void) tamedog(mtmp, (struct obj *)0);
X		       }
X		       break;
X		   }
X
X	     case 20:
X		    /* uncurse stuff */
X		   {  register struct obj *obj;
X
X			/* below plines added by GAN 10/30/86 */
X			You(Hallucination ?
X				"feel in touch with the Universal Oneness." :
X				"feel like someone is helping you.");
X			for(obj = invent; obj ; obj = obj->nobj)
X			       if(obj->owornmask || obj->otyp == LOADSTONE)
X					obj->cursed = 0;
X		       if(Punished) unpunish();
X		       break;
X		   }
X	     default: break;
X	  }
X}
X
Xvoid
Xdrown() {
X	register struct obj *obj;
X
X	/* Scrolls and potions get affected by the water */
X	for(obj = invent; obj; obj = obj->nobj) {
X		if(obj->olet == SCROLL_SYM && rn2(12) > Luck
X#ifdef MAIL
X			&& obj->otyp != SCR_MAIL
X#endif
X								)
X			obj->otyp = SCR_BLANK_PAPER;
X		if(obj->olet == POTION_SYM && rn2(12) > Luck) {
X			if (obj->spe == -1) {
X				obj->otyp = POT_WATER;
X				obj->blessed = obj->cursed = 0;
X				obj->spe = 0;
X			} else obj->spe--;
X		}
X	}
X
X#ifdef POLYSELF
X	if(u.umonnum == PM_GREMLIN && rn2(3)) {
X		struct monst *mtmp;
X		if(mtmp = cloneu()) {
X			mtmp->mhpmax = (u.mhmax /= 2);
X			You("multiply.");
X		}
X	}
X
X	if(is_swimmer(uasmon)) return;
X#endif
X
X	You("fell into %s!",
X	      levl[u.ux][u.uy].typ == POOL ? "a pool" : "the moat");
X	You("can't swim!");
X	if(
X#ifdef WIZARD
X	wizard ||
X#endif
X	rn2(3) < Luck+2) {
X		You("attempt a teleport spell.");	/* utcsri!carroll */
X		(void) dotele();
X		if(!is_pool(u.ux,u.uy)) return;
X	}
X	You("drown.");
X	killer_format = KILLED_BY_AN;
X	killer = levl[u.ux][u.uy].typ == POOL ? "pool of water" : "moat";
X	done(DROWNING);
X}
X
X#ifdef SPELLS
Xvoid
Xdrain_en(n)
Xregister int n;
X{
X	if (!u.uenmax) return;
X	You("feel your magical energy drain away!");
X	u.uen -= n;
X	if(u.uen < 0)  {
X		u.uenmax += u.uen;
X		if(u.uenmax < 0) u.uenmax = 0;
X		u.uen = 0;
X	}
X	flags.botl = 1;
X}
X#endif
X
Xint
Xdountrap() {	/* disarm a trapped object */
X	register struct obj *otmp;
X	register boolean confused = (Confusion > 0 || Hallucination > 0);
X	register int x,y;
X	int ch;
X	struct trap *ttmp;
X
X#ifdef POLYSELF
X	if(nohands(uasmon)) {
X	    pline("And just how do you expect to do that?");
X	    return(0);
X	}
X#endif
X	if(!getdir(TRUE)) return(0);
X	x = u.ux + u.dx;
X	y = u.uy + u.dy;
X
X	if(!u.dx && !u.dy) {
X	    for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
X		if(Is_box(otmp)) {
X		    pline("There is %s here, check for traps? ", doname(otmp));
X
X		    switch (ynq()) {
X			case 'q': return(0);
X			case 'n': continue;
X		    }
X
X		    if((otmp->otrapped && !confused 
X				&& rn2(MAXLEVEL+2-dlevel) < 10)
X		       || confused && !rn2(3)) {
X			You("find a trap on the %s!  Disarm it? ", xname(otmp));
X
X			switch (ynq()) {
X			    case 'q': return(1);
X			    case 'n': continue;
X			}
X
X			if(otmp->otrapped) {
X			    ch = 15 + (pl_character[0] == 'R') ? u.ulevel*3
X								: u.ulevel;
X			    if(confused || Fumbling || rnd(75+dlevel/2) > ch) {
X				You("set it off!");
X				(void) chest_trap(otmp, FINGER);
X			    } else {
X				You("disarm it!");
X				otmp->otrapped = 0;
X			    }
X			} else pline("That %s was not trapped.", doname(otmp));
X			return(1);
X		    } else {
X			You("find no traps on the %s.", xname(otmp));
X			return(1);
X		    }
X		}
X	    if ((ttmp = t_at(x,y)) && ttmp->tseen)
X		You("cannot disable this trap.");
X	    else
X		You("know of no traps here.");
X	    return(0);
X	}
X
X	if (!IS_DOOR(levl[x][y].typ)) {
X	    if ((ttmp = t_at(x,y)) && ttmp->tseen)
X		You("cannot disable that trap.");
X	    else
X		You("know of no traps there.");
X	    return(0);
X	}
X
X	switch (levl[x][y].doormask) {
X	    case D_NODOOR:
X		You("%s no door there.", Blind ? "feel" : "see");
X		return(0);
X	    case D_ISOPEN:
X		pline("This door is safely open.");
X		return(0);
X	    case D_BROKEN:
X		pline("This door is broken.");
X		return(0);
X	}
X
X	if ((levl[x][y].doormask & D_TRAPPED && !confused &&
X	     rn2(MAXLEVEL+2-dlevel) < 10)
X	    || confused && !rn2(3)) {
X		You("find a trap on the door!  Disarm it? ");
X		if (ynq() != 'y') return(1);
X		if (levl[x][y].doormask & D_TRAPPED) {
X		    ch = 15 +
X			 (pl_character[0] == 'R') ? u.ulevel*3 :
X			 u.ulevel;
X		    if(confused || Fumbling || rnd(75+dlevel/2) > ch) {
X			    You("set it off!");
X			    b_trapped("door");
X		    } else
X			    You("disarm it!");
X		    levl[x][y].doormask &= ~D_TRAPPED;
X		} else pline("This door was not trapped.");
X		return(1);
X	} else {
X		You("find no traps on the door.");
X		return(1);
X	}
X}
X
X/* only called when the player is doing something to the chest directly */
Xboolean
Xchest_trap(obj, bodypart)
Xregister struct obj *obj;
Xregister int bodypart;
X{
X	register struct obj *otmp,*otmp2;
X	char	buf[80];
X
X	if(Luck > -13 && rn2(13+Luck) > 7) return FALSE;
X
X	otmp = obj;
X	switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) {
X		case 25:
X		case 24:
X		case 23:
X		case 22:
X		case 21:
X			pline("The %s explodes!", xname(obj));
X			Sprintf(buf, "exploding %s", xname(obj));
X
X			delete_contents(obj);
X			for(otmp = level.objects[u.ux][u.uy];
X							otmp; otmp = otmp2) {
X			    otmp2 = otmp->nexthere;
X			    delobj(otmp);
X			}
X
X			losehp(d(6,6), buf, KILLED_BY_AN);
X			wake_nearby();
X			return TRUE;
X		case 20:
X		case 19:
X		case 18:
X		case 17:
X			pline("A cloud of noxious gas billows from the %s.",
X			      xname(obj));
X			poisoned("gas cloud", A_STR, "cloud of poison gas",15);
X			break;
X		case 16:
X		case 15:
X		case 14:
X		case 13:
X			You("feel a needle prick your %s.",body_part(bodypart));
X			poisoned("needle", A_CON, "poison needle",10);
X			break;
X		case 12:
X		case 11:
X		case 10:
X		case 9:
X			pline("A tower of flame erupts from the %s",
X			      xname(obj));
X			if(Fire_resistance) {
X			    shieldeff(u.ux, u.uy);
X			    You("don't seem to be affected.");
X			} else	losehp(d(4, 6), "tower of flame", KILLED_BY_AN);
X			destroy_item(SCROLL_SYM, AD_FIRE);
X#ifdef SPELLS
X			destroy_item(SPBOOK_SYM, AD_FIRE);
X#endif
X			destroy_item(POTION_SYM, AD_FIRE);
X			break;
X		case 8:
X		case 7:
X		case 6:
X			You("are jolted by a surge of electricity!");
X			if(Shock_resistance)  {
X			    shieldeff(u.ux, u.uy);
X			    You("don't seem to be affected.");
X			} else	losehp(d(4, 4), "electric shock", KILLED_BY_AN);
X			destroy_item(RING_SYM, AD_ELEC);
X			destroy_item(WAND_SYM, AD_ELEC);
X			break;
X		case 5:
X		case 4:
X		case 3:
X			pline("Suddenly you are frozen in place!");
X			nomul(-d(5, 6));
X			nomovemsg = "You can move again.";
X			break;
X		case 2:
X		case 1:
X		case 0:
X			pline("A cloud of %s gas billows from the %s",
X			      hcolor(), xname(obj));
X			if(!Stunned)
X			    if (Hallucination)
X				pline("What a groovy feeling!");
X			    else
X				You("stagger and your vision blurs...");
X			make_stunned(HStun + rn1(7, 16),FALSE);
X			make_hallucinated(Hallucination + rn1(5, 16),FALSE);
X			break;
X		default: impossible("bad chest trap");
X			break;
X	}
X	bot(); 			/* to get immediate botl re-display */
X	otmp->otrapped = 0;		/* these traps are one-shot things */
X
X	return FALSE;
X}
X
X#endif /* OVLB */
X#ifdef OVL2
X
Xvoid
Xwake_nearby() {			/* Wake up nearby monsters. */
X	register struct monst *mtmp;
X
X	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X	    if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
X		if(mtmp->msleep)  mtmp->msleep = 0;
X		if(mtmp->mtame)   EDOG(mtmp)->whistletime = moves;
X	    }
X	}
X}
X
X#endif /* OVL2 */
X#ifdef OVL0
X
Xstruct trap *
Xt_at(x,y)
Xregister int x, y;
X{
X	register struct trap *trap = ftrap;
X	while(trap) {
X		if(trap->tx == x && trap->ty == y) return(trap);
X		trap = trap->ntrap;
X	}
X	return((struct trap *)0);
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xdeltrap(trap)
Xregister struct trap *trap;
X{
X	register struct trap *ttmp;
X
X	if(trap == ftrap)
X		ftrap = ftrap->ntrap;
X	else {
X		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
X		ttmp->ntrap = trap->ntrap;
X	}
X	free((genericptr_t) trap);
X}
X
Xvoid
Xb_trapped(item)		/* used for doors. can be used */
Xregister const char *item;    /* for anything else that opens */
X{
X	register int dmg = rnd(5+(dlevel < 5 ? dlevel : 2+dlevel/2));
X
X	pline("KABOOM!!  The %s was booby-trapped!", item);
X	if(u.ulevel < 4 && dlevel < 3 && !rnl(3))
X		You("are shaken, but luckily unhurt.");		
X	else losehp(dmg, "explosion", KILLED_BY_AN);
X	make_stunned(HStun + dmg, TRUE);
X}
X
X/* Monster is hit by trap. */
X/* Note: doesn't work if both obj and d_override are null */
XSTATIC_OVL boolean
Xthitm(tlev, mon, obj, d_override)
Xregister int tlev;
Xregister struct monst *mon;
Xregister struct obj *obj;
Xint d_override;
X{
X	register int strike;
X	register boolean trapkilled = FALSE;
X
X	if (d_override) strike = 1;
X	else if (obj) strike = (mon->data->ac + tlev + obj->spe <= rnd(20));
X	else strike = (mon->data->ac + tlev <= rnd(20));
X
X	/* Actually more accurate than thitu, which doesn't take
X	 * obj->spe into account.
X	 */
X	if(!strike) {
X		if (cansee(mon->mx, mon->my))
X			pline("%s is almost hit by %s!", Monnam(mon),
X								doname(obj));
X	} else {
X		int dam = 1;
X
X		if (obj && cansee(mon->mx, mon->my))
X			pline("%s is hit by %s!", Monnam(mon), doname(obj));
X		if (d_override) dam = d_override;
X		else if (obj) {
X			dam = dmgval(obj, mon->data);
X			if (dam < 1) dam = 1;
X		}
X		if ((mon->mhp -= dam) <= 0) {
X			int xx = mon->mx;
X			int yy = mon->my;
X
X			if (cansee(mon->mx, mon->my))
X				pline("%s is killed!", Monnam(mon));
X			else if (mon->mtame)
X	You("have a sad feeling for a moment, then it passes.");
X			mondied(mon);
X			newsym(xx, yy);
X			trapkilled = TRUE;
X		}
X	}
X	if (obj && (!strike || d_override)) {
X		place_object(obj, mon->mx, mon->my);
X		obj->nobj = fobj;
X		fobj = obj;
X		stackobj(fobj);
X	} else if (obj) free ((genericptr_t)obj);
X
X	return trapkilled;
X}
X
Xboolean
Xunconscious()
X{
X	return (multi < 0 && (!nomovemsg ||
X		!strncmp(nomovemsg,"You wake", 8) ||
X		!strncmp(nomovemsg,"You awake", 9) ||
X		!strncmp(nomovemsg,"You regain con", 15) ||
X		!strncmp(nomovemsg,"You are consci", 15)));
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 42990 -ne `wc -c <'src/trap.c'`; then
    echo shar: \"'src/trap.c'\" unpacked with wrong size!
fi
# end of 'src/trap.c'
fi
echo shar: End of archive 8 \(of 56\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 56 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0