From bacchus.pa.dec.com!decwrl!ucbvax!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!mit-eddie!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr Thu Jul 12 20:22:19 PDT 1990 Article 974 of comp.sources.games: Path: bacchus.pa.dec.com!decwrl!ucbvax!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!mit-eddie!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v10i053: nethack3p9 - display oriented dungeons & dragons (Ver. 3.0i), Part08/56 Message-ID: <5908@tekred.CNA.TEK.COM> Date: 12 Jul 90 00:29:03 GMT Sender: news@tekred.CNA.TEK.COM Lines: 2616 Approved: billr@saab.CNA.TEK.COM Submitted-by: Izchak Miller 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 '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