games-request@tekred.TEK.COM (07/28/87)
Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 2, Issue 5
Archive-name: nethack/Part05
#! /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 5 (of 16)."
# Contents: apply.c date.h mon.c trap.c
# Wrapped by billr@tekred on Tue Jul 28 09:49:26 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f apply.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"apply.c\"
else
echo shar: Extracting \"apply.c\" \(13923 characters\)
sed "s/^X//" >apply.c <<'END_OF_apply.c'
X/* SCCS Id: @(#)apply.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* apply.c - version 1.0.3 */
X
X#include "hack.h"
X#include "edog.h"
X#include "mkroom.h"
Xstatic struct monst *bchit();
Xextern struct obj *addinv();
Xextern struct trap *maketrap();
Xextern int (*occupation)();
Xextern char *occtxt;
Xextern char quitchars[];
Xextern char pl_character[];
X
X#ifdef KAA
Xextern boolean unweapon;
X#endif
Xstatic use_camera(), use_ice_box(), use_whistle();
Xstatic use_magic_whistle(), use_pick_axe();
X#ifdef MARKER
Xextern int dowrite();
X#endif
X
Xdoapply() {
X register struct obj *obj;
X register int res = 1;
X
X obj = getobj("(", "use or apply");
X if(!obj) return(0);
X
X switch(obj->otyp){
X case EXPENSIVE_CAMERA:
X use_camera(obj); break;
X case ICE_BOX:
X use_ice_box(obj); break;
X case PICK_AXE:
X res = use_pick_axe(obj);
X break;
X
X case MAGIC_WHISTLE:
X if(pl_character[0] == 'W' || u.ulevel > 9) {
X use_magic_whistle(obj);
X break;
X }
X /* fall into next case */
X case WHISTLE:
X use_whistle(obj);
X break;
X#ifdef WALKIES
X case LEASH:
X use_leash(obj);
X break;
X#endif
X#ifdef MARKER
X case MAGIC_MARKER:
X dowrite(obj);
X break;
X#endif
X case CAN_OPENER:
X if(!carrying(TIN)) {
X pline("You have no can to open.");
X goto xit;
X }
X pline("You cannot open a tin without eating its contents.");
X pline("In order to eat, use the 'e' command.");
X if(obj != uwep)
X pline("Opening the tin will be much easier if you wield the can-opener.");
X goto xit;
X
X#ifdef KAA
X case STETHOSCOPE:
X res = use_stethoscope(obj);
X break;
X#endif
X default:
X pline("Sorry, I don't know how to use that.");
X xit:
X nomul(0);
X return(0);
X }
X nomul(0);
X return(res);
X}
X
X/* ARGSUSED */
Xstatic
Xuse_camera(obj) /* register */ struct obj *obj; {
Xregister struct monst *mtmp;
X if(!getdir(1)){ /* ask: in what direction? */
X flags.move = multi = 0;
X return;
X }
X if(u.uswallow) {
X pline("You take a picture of %s's stomach.", monnam(u.ustuck));
X return;
X }
X if(u.dz) {
X pline("You take a picture of the %s.",
X (u.dz > 0) ? "floor" : "ceiling");
X return;
X }
X#ifdef KAA
X if(!u.dx && !u.dy && !u.dz) {
X if(!Blind) {
X pline("You are blinded by the flash!");
X Blind += rnd(25);
X seeoff(0);
X }
X return;
X }
X#endif
X if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) {
X if(mtmp->msleep){
X mtmp->msleep = 0;
X pline("The flash awakens %s.", monnam(mtmp)); /* a3 */
X } else
X if(mtmp->data->mlet != 'y')
X if(mtmp->mcansee || mtmp->mblinded){
X register int tmp = dist(mtmp->mx,mtmp->my);
X register int tmp2;
X if(cansee(mtmp->mx,mtmp->my))
X pline("%s is blinded by the flash!", Monnam(mtmp));
X setmangry(mtmp);
X if(tmp < 9 && !mtmp->isshk && rn2(4)) {
X mtmp->mflee = 1;
X if(rn2(4)) mtmp->mfleetim = rnd(100);
X }
X if(tmp < 3) mtmp->mcansee = mtmp->mblinded = 0;
X else {
X tmp2 = mtmp->mblinded;
X tmp2 += rnd(1 + 50/tmp);
X if(tmp2 > 127) tmp2 = 127;
X mtmp->mblinded = tmp2;
X mtmp->mcansee = 0;
X }
X }
X }
X}
X
X#ifdef KAA
X/* Strictly speaking it makes no sense for usage of a stethoscope to
X not take any time; however, unless it did, the stethoscope would be
X almost useless. */
Xstatic use_stethoscope(obj) register struct obj *obj; {
Xregister struct monst *mtmp;
Xregister struct rm *lev;
Xregister int rx, ry;
X if(!freehand()) {
X pline("You have no free hand!");
X return(1);
X }
X if (!getdir(1)) {
X flags.move=multi=0;
X return(0);
X }
X if(u.dz < 0 || (u.dz && Levitation)) {
X pline("You can't reach the %s!", u.dz<0 ? "ceiling" : "floor");
X return(1);
X }
X if(u.dz) {
X pline("The floor seems healthy enough.");
X return(0);
X }
X if (Confusion) confdir();
X rx = u.ux + u.dx; ry = u.uy + u.dy;
X if(u.uswallow) {
X mstatusline(u.ustuck);
X return(0);
X }
X if(mtmp=m_at(rx,ry)) {
X mstatusline(mtmp);
X return(0);
X }
X if (!isok(rx,ry)) {
X pline("You hear the sounds at the end of the universe.");
X return(0);
X }
X lev = &levl[rx][ry];
X if(lev->typ == SDOOR) {
X pline("You hear a hollow sound! This must be a secret door!");
X lev->typ = DOOR;
X#ifdef DGK
X atl(rx, ry, symbol.door);
X#else
X atl(rx, ry, DOOR_SYM);
X#endif
X return(0);
X }
X if(lev->typ == SCORR) {
X pline("You hear a hollow sound! This must be a secret passage!");
X lev->typ = CORR;
X atl(rx, ry, CORR_SYM);
X return(0);
X }
X pline("You hear nothing special.");
X return(0);
X}
X#endif
X
Xstatic
Xstruct obj *current_ice_box; /* a local variable of use_ice_box, to be
X used by its local procedures in/ck_ice_box */
Xstatic
Xin_ice_box(obj) register struct obj *obj; {
X if(obj == current_ice_box ||
X (Punished && (obj == uball || obj == uchain))){
X pline("You must be kidding.");
X return(0);
X }
X if(obj->owornmask & (W_ARMOR | W_RING)) {
X pline("You cannot refrigerate something you are wearing.");
X return(0);
X }
X if(obj->owt + current_ice_box->owt > 70) {
X pline("It won't fit.");
X return(1); /* be careful! */
X }
X if(obj == uwep) {
X if(uwep->cursed) {
X pline("Your weapon is welded to your hand!");
X return(0);
X }
X setuwep((struct obj *) 0);
X }
X current_ice_box->owt += obj->owt;
X freeinv(obj);
X obj->o_cnt_id = current_ice_box->o_id;
X obj->nobj = fcobj;
X fcobj = obj;
X obj->age = moves - obj->age; /* actual age */
X return(1);
X}
X
Xstatic
Xck_ice_box(obj) register struct obj *obj; {
X return(obj->o_cnt_id == current_ice_box->o_id);
X}
X
Xstatic
Xout_ice_box(obj) register struct obj *obj; {
Xregister struct obj *otmp;
X if(obj == fcobj) fcobj = fcobj->nobj;
X else {
X for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj)
X if(!otmp->nobj) panic("out_ice_box");
X otmp->nobj = obj->nobj;
X }
X current_ice_box->owt -= obj->owt;
X obj->age = moves - obj->age; /* simulated point of time */
X (void) addinv(obj);
X}
X
Xstatic
Xuse_ice_box(obj) register struct obj *obj; {
Xregister int cnt = 0;
Xregister struct obj *otmp;
X current_ice_box = obj; /* for use by in/out_ice_box */
X for(otmp = fcobj; otmp; otmp = otmp->nobj)
X if(otmp->o_cnt_id == obj->o_id)
X cnt++;
X if(!cnt) pline("Your ice-box is empty.");
X else {
X pline("Do you want to take something out of the ice-box? [yn] ");
X if(readchar() == 'y')
X if(askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0))
X return;
X pline("That was all. Do you wish to put something in? [yn] ");
X if(readchar() != 'y') return;
X }
X /* call getobj: 0: allow cnt; #: allow all types; %: expect food */
X otmp = getobj("0#%", "put in");
X if(!otmp || !in_ice_box(otmp))
X flags.move = multi = 0;
X}
X
Xstatic
Xstruct monst *
Xbchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; {
X register struct monst *mtmp = (struct monst *) 0;
X register int bchx = u.ux, bchy = u.uy;
X
X if(sym) Tmp_at(-1, sym); /* open call */
X while(range--) {
X bchx += ddx;
X bchy += ddy;
X if(mtmp = m_at(bchx,bchy))
X break;
X if(!ZAP_POS(levl[bchx][bchy].typ)) {
X bchx -= ddx;
X bchy -= ddy;
X break;
X }
X if(sym) Tmp_at(bchx, bchy);
X }
X if(sym) Tmp_at(-1, -1);
X return(mtmp);
X}
X
X/* ARGSUSED */
Xstatic
Xuse_whistle(obj) struct obj *obj; {
Xregister struct monst *mtmp = fmon;
X pline("You produce a high whistling sound.");
X while(mtmp) {
X if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
X if(mtmp->msleep)
X mtmp->msleep = 0;
X if(mtmp->mtame)
X EDOG(mtmp)->whistletime = moves;
X }
X mtmp = mtmp->nmon;
X }
X}
X
X/* ARGSUSED */
Xstatic
Xuse_magic_whistle(obj) struct obj *obj; {
Xregister struct monst *mtmp = fmon;
X pline("You produce a strange whistling sound.");
X while(mtmp) {
X if(mtmp->mtame) mnexto(mtmp);
X mtmp = mtmp->nmon;
X }
X}
X
X#ifdef WALKIES
X/* ARGSUSED */
Xstatic
Xuse_leash(obj) struct obj *obj; {
Xregister struct monst *mtmp = fmon;
X
X while(mtmp && !mtmp->mleashed) mtmp = mtmp->nmon;
X
X if(mtmp) {
X
X if (next_to(mtmp)) {
X
X mtmp->mleashed = 0;
X pline("You remove the leash from your %s.",
X mtmp->data->mname);
X } else pline("You must be next to your %s to unleash him.",
X mtmp->data->mname);
X } else {
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X
X if(mtmp->mtame && next_to(mtmp)) {
X
X pline("You slip the leash around your %s.", mtmp->data->mname);
X mtmp->mleashed = 1;
X if(mtmp->msleep) mtmp->msleep = 0;
X return(0);
X }
X }
X pline("There's nothing here to put a leash on.");
X }
X return(0);
X}
X
Xnext_to(mtmp) register struct monst *mtmp; {
X
X return((abs(u.ux - mtmp->mx) <= 1) && (abs(u.uy - mtmp->my) <= 1));
X}
X#endif
X
Xstatic int dig_effort; /* effort expended on current pos */
Xstatic uchar dig_level;
Xstatic coord dig_pos;
Xstatic boolean dig_down;
X
Xstatic
Xdig() {
X register struct rm *lev;
X register dpx = dig_pos.x, dpy = dig_pos.y;
X
X /* perhaps a nymph stole his pick-axe while he was busy digging */
X /* or perhaps he teleported away */
X if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
X dig_level != dlevel ||
X ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
X (!dig_down && dist(dpx,dpy) > 2)))
X return(0);
X
X dig_effort += 10 + abon() + uwep->spe + rn2(5);
X if(dig_down) {
X if(!xdnstair) {
X pline("The floor here seems too hard to dig in.");
X return(0);
X }
X if(dig_effort > 250) {
X dighole();
X return(0); /* done with digging */
X }
X if(dig_effort > 50) {
X register struct trap *ttmp = t_at(dpx,dpy);
X
X if(!ttmp) {
X ttmp = maketrap(dpx,dpy,PIT);
X ttmp->tseen = 1;
X pline("You have dug a pit.");
X u.utrap = rn1(4,2);
X u.utraptype = TT_PIT;
X return(0);
X }
X }
X } else
X if(dig_effort > 100) {
X register char *digtxt;
X register struct obj *obj;
X
X lev = &levl[dpx][dpy];
X if(obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) {
X fracture_rock(obj);
X digtxt = "The rock falls apart.";
X } else if(!lev->typ || lev->typ == SCORR) {
X lev->typ = CORR;
X digtxt = "You succeeded in cutting away some rock.";
X } else if(lev->typ == HWALL || lev->typ == VWALL
X || lev->typ == SDOOR) {
X lev->typ = xdnstair ? DOOR : ROOM;
X digtxt = "You just made an opening in the wall.";
X } else
X digtxt = "Now what exactly was it that you were digging in?";
X mnewsym(dpx, dpy);
X prl(dpx, dpy);
X pline(digtxt); /* after mnewsym & prl */
X return(0);
X } else {
X if(IS_WALL(levl[dpx][dpy].typ)) {
X register int rno = inroom(dpx,dpy);
X
X if(rno >= 0 && rooms[rno].rtype >= 8) {
X pline("This wall seems too hard to dig into.");
X return(0);
X }
X }
X pline("You hit the rock with all your might.");
X }
X return(1);
X}
X
X/* When will hole be finished? Very rough indication used by shopkeeper. */
Xholetime() {
X return( (occupation == dig) ? (250 - dig_effort)/20 : -1);
X}
X
Xdighole()
X{
X register struct trap *ttmp = t_at(u.ux, u.uy);
X
X if(!xdnstair) {
X pline("The floor here seems too hard to dig in.");
X } else {
X if(ttmp)
X ttmp->ttyp = TRAPDOOR;
X else
X ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
X ttmp->tseen = 1;
X pline("You've made a hole in the floor.");
X if(!u.ustuck && !Levitation) { /* KAA */
X if(inshop())
X shopdig(1);
X pline("You fall through ...");
X if(u.utraptype == TT_PIT) {
X u.utrap = 0;
X u.utraptype = 0;
X }
X goto_level(dlevel+1, FALSE);
X }
X }
X}
X
Xstatic
Xuse_pick_axe(obj)
Xstruct obj *obj;
X{
X char dirsyms[12];
X extern char sdir[];
X register char *dsp = dirsyms, *sdp = sdir;
X register struct monst *mtmp;
X register struct rm *lev;
X register int rx, ry, res = 0;
X
X#ifndef FREEHAND
X /* edited by GAN 10/20/86 so that you can't apply the
X * pick-axe while wielding a cursed weapon
X */
X if(!freehand()) {
X pline("You have no free hand to dig with!");
X return(0);
X }
X# ifdef KAA
X if(cantwield(u.usym)) {
X pline("You can't hold it strongly enough.");
X return(0);
X }
X# endif
X#else
X if(obj != uwep) {
X if(uwep && uwep->cursed) {
X /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
X pline("Since your weapon is welded to your hand,");
X pline("you cannot use that pick-axe.");
X return(0);
X }
X# ifdef KAA
X if(cantwield(u.usym)) {
X pline("You can't hold it strongly enough.");
X return(0);
X }
X unweapon = TRUE;
X# endif
X pline("You now wield %s.", doname(obj));
X setuwep(obj);
X res = 1;
X }
X#endif
X while(*sdp) {
X (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */
X rx = u.ux + u.dx;
X ry = u.uy + u.dy;
X if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
X (IS_ROCK(levl[rx][ry].typ)
X || sobj_at(ENORMOUS_ROCK, rx, ry))))
X *dsp++ = *sdp;
X sdp++;
X }
X *dsp = 0;
X pline("In what direction do you want to dig? [%s] ", dirsyms);
X if(!getdir(0)) /* no txt */
X return(res);
X if(u.uswallow && attack(u.ustuck)) /* return(1) */;
X else
X if(u.dz < 0)
X pline("You cannot reach the ceiling.");
X else
X#ifdef KAA
X if(!u.dx && !u.dy && !u.dz) {
X pline("You hit yourself with your own pick-axe.");
X losehp(rnd(2)+dbon(), "self-inflicted wound");
X flags.botl=1;
X return(1);
X }
X#endif
X if(u.dz == 0) {
X if(Confusion)
X confdir();
X rx = u.ux + u.dx;
X ry = u.uy + u.dy;
X if((mtmp = m_at(rx, ry)) && attack(mtmp))
X return(1);
X if(!isok(rx, ry)) {
X pline("Clash!");
X return(1);
X }
X lev = &levl[rx][ry];
X if(lev->typ == DOOR)
X pline("Your %s against the door.",
X aobjnam(obj, "clang"));
X else if(!IS_ROCK(lev->typ)
X && !sobj_at(ENORMOUS_ROCK, rx, ry)) {
X /* ACCESSIBLE or POOL */
X pline("You swing your %s through thin air.",
X aobjnam(obj, (char *) 0));
X } else {
X if(dig_pos.x != rx || dig_pos.y != ry
X || dig_level != dlevel || dig_down) {
X dig_down = FALSE;
X dig_pos.x = rx;
X dig_pos.y = ry;
X dig_level = dlevel;
X dig_effort = 0;
X pline("You start digging.");
X } else
X pline("You continue digging.");
X#ifdef DGKMOD
X set_occupation(dig, "digging", 0);
X#else
X occupation = dig;
X occtxt = "digging";
X#endif
X }
X } else if(Levitation) {
X pline("You cannot reach the floor.");
X } else {
X if(dig_pos.x != u.ux || dig_pos.y != u.uy
X || dig_level != dlevel || !dig_down) {
X dig_down = TRUE;
X dig_pos.x = u.ux;
X dig_pos.y = u.uy;
X dig_level = dlevel;
X dig_effort = 0;
X pline("You start digging in the floor.");
X if(inshop())
X shopdig(0);
X } else
X pline("You continue digging in the floor.");
X#ifdef DGKMOD
X set_occupation(dig, "digging", 0);
X#else
X occupation = dig;
X occtxt = "digging";
X#endif
X }
X return(1);
X}
END_OF_apply.c
if test 13923 -ne `wc -c <apply.c`; then
echo shar: \"apply.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f date.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"date.h\"
else
echo shar: Extracting \"date.h\" \(88 characters\)
sed "s/^X//" >date.h <<'END_OF_date.h'
X/* SCCS Id: @(#)date.h 1.3 87/07/14 */
X
Xchar datestring[] = "Fri Jun 26 11:49:16 1987";
END_OF_date.h
if test 88 -ne `wc -c <date.h`; then
echo shar: \"date.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f mon.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"mon.c\"
else
echo shar: Extracting \"mon.c\" \(17706 characters\)
sed "s/^X//" >mon.c <<'END_OF_mon.c'
X/* SCCS Id: @(#)mon.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* mon.c - version 1.0.3 */
X
X#include "hack.h"
X#include "mfndpos.h"
Xextern struct obj *mkobj_at();
Xextern char *hcolor();
X#ifdef KAA
Xextern boolean stoned;
Xextern char mlarge[];
X#endif
X
Xint warnlevel; /* used by movemon and dochugw */
Xlong lastwarntime;
Xint lastwarnlev;
Xchar *warnings[] = { "white", "pink", "red", "ruby", "purple", "black" };
X
Xmovemon()
X{
X register struct monst *mtmp;
X register int fr;
X
X warnlevel = 0;
X
X while(1) {
X /* find a monster that we haven't treated yet */
X /* note that mtmp or mtmp->nmon might get killed
X while mtmp moves, so we cannot just walk down the
X chain (even new monsters might get created!) */
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mlstmv < moves) goto next_mon;
X /* treated all monsters */
X break;
X
X next_mon:
X mtmp->mlstmv = moves;
X
X /* most monsters drown in pools */
X { boolean inpool, iseel;
X
X inpool = (levl[mtmp->mx][mtmp->my].typ == POOL);
X iseel = (mtmp->data->mlet == ';');
X if(inpool && !iseel) {
X if(cansee(mtmp->mx,mtmp->my))
X pline("%s drowns.", Monnam(mtmp));
X mondead(mtmp);
X continue;
X }
X /* but eels have a difficult time outside */
X if(iseel && !inpool) {
X if(mtmp->mhp > 1) mtmp->mhp--;
X mtmp->mflee = 1;
X mtmp->mfleetim += 2;
X }
X }
X if(mtmp->mblinded && !--mtmp->mblinded)
X mtmp->mcansee = 1;
X if(mtmp->mfleetim && !--mtmp->mfleetim)
X mtmp->mflee = 0;
X /* unwatched mimics and piercers may hide again [MRS] */
X if(restrap(mtmp)) continue;
X if(mtmp->mimic) continue;
X if(mtmp->mspeed != MSLOW || !(moves%2)){
X /* continue if the monster died fighting */
X fr = -1;
X if(Conflict && cansee(mtmp->mx,mtmp->my)
X && (fr = fightm(mtmp)) == 2)
X continue;
X if(fr<0 && dochugw(mtmp))
X continue;
X }
X if(mtmp->mspeed == MFAST && dochugw(mtmp))
X continue;
X }
X
X warnlevel -= u.ulevel;
X if(warnlevel >= SIZE(warnings))
X warnlevel = SIZE(warnings)-1;
X if(warnlevel >= 0)
X if(warnlevel > lastwarnlev || moves > lastwarntime + 5){
X register char *rr;
X switch(Warning & (LEFT_RING | RIGHT_RING)){
X case LEFT_RING:
X rr = "Your left ring glows";
X break;
X case RIGHT_RING:
X rr = "Your right ring glows";
X break;
X case LEFT_RING | RIGHT_RING:
X rr = "Both your rings glow";
X break;
X default:
X rr = "Your fingertips glow";
X break;
X }
X pline("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]);
X lastwarntime = moves;
X lastwarnlev = warnlevel;
X }
X
X dmonsfree(); /* remove all dead monsters */
X}
X
Xjustswld(mtmp,name)
Xregister struct monst *mtmp;
Xchar *name;
X{
X
X mtmp->mx = u.ux;
X mtmp->my = u.uy;
X u.ustuck = mtmp;
X pmon(mtmp);
X kludge("%s swallows you!",name);
X more();
X seeoff(1);
X u.uswallow = 1;
X u.uswldtim = 0;
X swallowed();
X}
X
Xyouswld(mtmp,dam,die,name)
Xregister struct monst *mtmp;
Xregister dam,die;
Xchar *name;
X{
X if(mtmp != u.ustuck) return;
X kludge("%s digests you!",name);
X u.uhp -= dam;
X if(u.uswldtim++ >= die){ /* a3 */
X pline("It totally digests you!");
X u.uhp = -1;
X }
X if(u.uhp < 1) done_in_by(mtmp);
X /* flags.botlx = 1; /* should we show status line ? */
X}
X
X#ifdef ROCKMOLE
Xmeatgold(mtmp) register struct monst *mtmp; {
Xregister struct gold *gold;
Xregister int pile;
Xregister struct obj *otmp;
X /* Eats gold if it is there */
X while(gold = g_at(mtmp->mx, mtmp->my)){
X freegold(gold);
X /* Left behind a pile? */
X pile = rnd(25);
X if(pile < 3)
X mksobj_at(ROCK, mtmp->mx, mtmp->my);
X newsym(mtmp->mx, mtmp->my);
X }
X /* Eats armor if it is there */
X otmp = o_at(mtmp->mx,mtmp->my);
X if((otmp) && (otmp->otyp >= PLATE_MAIL) && (otmp->otyp <= RING_MAIL)){
X freeobj(otmp);
X /* Left behind a pile? */
X pile = rnd(25);
X if(pile < 3)
X mksobj_at(ROCK, mtmp->mx, mtmp->my);
X newsym(mtmp->mx, mtmp->my);
X }
X}
X#endif /* ROCKMOLE /**/
X
Xmpickgold(mtmp) register struct monst *mtmp; {
Xregister struct gold *gold;
Xregister struct obj *otmp;
X while(gold = g_at(mtmp->mx, mtmp->my)){
X mtmp->mgold += gold->amount;
X freegold(gold);
X if(levl[mtmp->mx][mtmp->my].scrsym == '$')
X newsym(mtmp->mx, mtmp->my);
X }
X}
X
X/* Now includes giants which pick up enormous rocks. KAA */
Xmpickgems(mtmp) register struct monst *mtmp; {
Xregister struct obj *otmp;
X for(otmp = fobj; otmp; otmp = otmp->nobj)
X if(otmp->olet ==
X#ifdef KAA
X (mtmp->data->mlet=='9' ? ROCK_SYM : GEM_SYM))
X#else
X GEM_SYM)
X#endif
X if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my)
X if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){
X freeobj(otmp);
X mpickobj(mtmp, otmp);
X#ifndef KAA
X if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM)
X#endif
X newsym(mtmp->mx, mtmp->my); /* %% */
X return; /* pick only one object */
X }
X}
X
X/* return number of acceptable neighbour positions */
Xmfndpos(mon,poss,info,flag)
Xregister struct monst *mon;
Xcoord poss[9];
Xlong info[9], flag;
X{
X register int x,y,nx,ny,cnt = 0,ntyp;
X register struct monst *mtmp;
X int nowtyp;
X boolean pool;
X
X x = mon->mx;
X y = mon->my;
X nowtyp = levl[x][y].typ;
X
X pool = (mon->data->mlet == ';');
Xnexttry: /* eels prefer the water, but if there is no water nearby,
X they will crawl over land */
X if(mon->mconf) {
X flag |= ALLOW_ALL;
X flag &= ~NOTONL;
X }
X for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
X if(nx != x || ny != y) if(isok(nx,ny))
X#ifdef ROCKMOLE
X if(!IS_ROCK(ntyp = levl[nx][ny].typ) || (flag & ALLOW_WALL))
X#else
X if(!IS_ROCK(ntyp = levl[nx][ny].typ))
X#endif
X if(!(nx != x && ny != y && (nowtyp == DOOR || ntyp == DOOR)))
X if((ntyp == POOL) == pool) {
X info[cnt] = 0;
X if(nx == u.ux && ny == u.uy){
X if(!(flag & ALLOW_U)) continue;
X info[cnt] = ALLOW_U;
X } else if(mtmp = m_at(nx,ny)){
X if(!(flag & ALLOW_M)) continue;
X info[cnt] = ALLOW_M;
X if(mtmp->mtame){
X if(!(flag & ALLOW_TM)) continue;
X info[cnt] |= ALLOW_TM;
X }
X }
X if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
X if(flag & NOGARLIC) continue;
X info[cnt] |= NOGARLIC;
X }
X if(sobj_at(SCR_SCARE_MONSTER, nx, ny) ||
X (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) {
X if(!(flag & ALLOW_SSM)) continue;
X info[cnt] |= ALLOW_SSM;
X }
X if(sobj_at(ENORMOUS_ROCK, nx, ny)) {
X if(!(flag & ALLOW_ROCK)) continue;
X info[cnt] |= ALLOW_ROCK;
X }
X if(!Invis && online(nx,ny)){
X if(flag & NOTONL) continue;
X info[cnt] |= NOTONL;
X }
X /* we cannot avoid traps of an unknown kind */
X { register struct trap *ttmp = t_at(nx, ny);
X register int tt;
X if(ttmp) {
X tt = 1 << ttmp->ttyp;
X /* below if added by GAN 02/06/87 to avoid
X * traps out of range
X */
X if(!(tt & ALLOW_TRAPS)) {
X impossible("A monster looked at a very strange trap");
X continue;
X }
X if(mon->mtrapseen & tt){
X if(!(flag & tt)) continue;
X info[cnt] |= tt;
X }
X }
X }
X poss[cnt].x = nx;
X poss[cnt].y = ny;
X cnt++;
X }
X if(!cnt && pool && nowtyp != POOL) {
X pool = FALSE;
X goto nexttry;
X }
X return(cnt);
X}
X
Xdist(x,y) int x,y; {
X return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy));
X}
X
Xpoisoned(string, pname)
Xregister char *string, *pname;
X{
X register i, plural;
X
X plural = (string[strlen(string) - 1] == 's')? 1 : 0;
X if(Blind) {
X if (plural) pline("They were poisoned.");
X else pline("It was poisoned.");
X } else {
X if (plural) pline("The %s were poisoned!", string);
X else pline("The %s was poisoned!", string);
X }
X
X if(Poison_resistance) {
X pline("The poison doesn't seem to affect you.");
X return;
X }
X i = rn2(10);
X if(i == 0) {
X u.uhp = -1;
X pline("I am afraid the poison was deadly ...");
X } else if(i <= 5) {
X losestr(rn1(3,3));
X } else {
X losehp(rn1(10,6), pname);
X }
X if(u.uhp < 1) {
X killer = pname;
X done("died");
X }
X}
X
Xmondead(mtmp)
Xregister struct monst *mtmp;
X{
X relobj(mtmp,1);
X unpmon(mtmp);
X relmon(mtmp);
X unstuck(mtmp);
X#ifdef KOPS
X if(mtmp->data->mlet == 'K') {
X /* When a Kop dies, he probably comes back. */
X register int fate = rnd(3);
X if(fate == 1) {
X /* returns near the stairs */
X mkmon_at('K',xdnstair,ydnstair);
X } else if(fate == 2) {
X /* randomly */
X mkmon_at('K',0,0);
X }
X }
X#endif
X if(mtmp->isshk) shkdead(mtmp);
X if(mtmp->isgd) gddead();
X#ifndef NOWORM
X if(mtmp->wormno) wormdead(mtmp);
X#endif
X#ifdef HARD
X if(mtmp->data->mlet == '1') wizdead(mtmp);
X#endif
X monfree(mtmp);
X}
X
X/* called when monster is moved to larger structure */
Xreplmon(mtmp,mtmp2)
Xregister struct monst *mtmp, *mtmp2;
X{
X relmon(mtmp);
X monfree(mtmp);
X mtmp2->nmon = fmon;
X fmon = mtmp2;
X if(u.ustuck == mtmp) u.ustuck = mtmp2;
X if(mtmp2->isshk) replshk(mtmp,mtmp2);
X if(mtmp2->isgd) replgd(mtmp,mtmp2);
X}
X
Xrelmon(mon)
Xregister struct monst *mon;
X{
X register struct monst *mtmp;
X
X if (fmon == 0) panic ("relmon: no fmon available.");
X
X if(mon == fmon) fmon = fmon->nmon;
X else {
X for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ;
X mtmp->nmon = mon->nmon;
X }
X}
X
X/* we do not free monsters immediately, in order to have their name
X available shortly after their demise */
Xstruct monst *fdmon; /* chain of dead monsters, need not to be saved */
X
Xmonfree(mtmp) register struct monst *mtmp; {
X mtmp->nmon = fdmon;
X fdmon = mtmp;
X}
X
Xdmonsfree(){
Xregister struct monst *mtmp;
X while(mtmp = fdmon){
X fdmon = mtmp->nmon;
X free((char *) mtmp);
X }
X}
X
Xunstuck(mtmp)
Xregister struct monst *mtmp;
X{
X if(u.ustuck == mtmp) {
X if(u.uswallow){
X u.ux = mtmp->mx;
X u.uy = mtmp->my;
X u.uswallow = 0;
X setsee();
X docrt();
X }
X u.ustuck = 0;
X }
X}
X
Xkilled(mtmp)
Xregister struct monst *mtmp;
X{
X xkilled(mtmp, 1);
X}
X
Xxkilled(mtmp, dest)
Xregister struct monst *mtmp;
Xint dest;
X/* Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse
X either; dest=3, message but no corpse */
X{
X#ifdef lint
X#define NEW_SCORING
X#endif
X register int tmp,tmp2,nk,x,y;
X register struct permonst *mdat = mtmp->data;
X extern long newuexp();
X
X if(mtmp->cham) mdat = PM_CHAMELEON;
X if (dest & 1) {
X if(Blind) pline("You destroy it!");
X else {
X pline("You destroy %s!",
X mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp));
X }
X }
X if(u.umconf) {
X if(!Blind)
X {
X pline("Your hands stop glowing %s.",
X Hallucination ? hcolor() : "blue");
X }
X u.umconf = 0;
X }
X
X /* count killed monsters */
X#define MAXMONNO 100
X nk = 1; /* in case we cannot find it in mons */
X tmp = mdat - mons; /* index in mons array (if not 'd', '@', ...) */
X if(tmp >= 0 && tmp < CMNUM+2) {
X extern char fut_geno[];
X u.nr_killed[tmp]++;
X if((nk = u.nr_killed[tmp]) > MAXMONNO &&
X !index(fut_geno, mdat->mlet))
X charcat(fut_geno, mdat->mlet);
X }
X
X /* punish bad behaviour */
X if(mdat->mlet == '@') {
X HTelepat = 0;
X u.uluck -= 2;
X }
X if(mtmp->mpeaceful || mtmp->mtame) u.uluck--;
X if(mdat->mlet == 'u') u.uluck -= 5;
X if((int)u.uluck < LUCKMIN) u.uluck = LUCKMIN;
X
X /* give experience points */
X tmp = 1 + mdat->mlevel * mdat->mlevel;
X if(mdat->ac < 3) tmp += 2*(7 - mdat->ac);
X#ifdef KAA
X if(index("AcsSDXaeRTVWU&In:P9", mdat->mlet))
X#else
X if(index("AcsSDXaeRTVWU&In:P", mdat->mlet))
X#endif
X tmp += 2*mdat->mlevel;
X if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel);
X if(mdat->mlevel > 6) tmp += 50;
X if(mdat->mlet == ';') tmp += 1000;
X
X#ifdef NEW_SCORING
X /* ------- recent addition: make nr of points decrease
X when this is not the first of this kind */
X { int ul = u.ulevel;
X int ml = mdat->mlevel;
X
X if(ul < 14) /* points are given based on present and future level */
X for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++)
X if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk
X >= 10*pow((unsigned)(ul-1)))
X if(++ul == 14) break;
X
X tmp2 = ml - ul -1;
X tmp = (tmp + ((tmp2 < 0) ? 0 : 4<<tmp2))/nk;
X if(!tmp) tmp = 1;
X }
X /* note: ul is not necessarily the future value of u.ulevel */
X /* ------- end of recent valuation change ------- */
X#endif /* NEW_SCORING /**/
X
X more_experienced(tmp,0);
X flags.botl = 1;
X while(u.ulevel < 14 && u.uexp >= newuexp()){
X pline("Welcome to experience level %u.", ++u.ulevel);
X tmp = rnd(10);
X if(tmp < 3) tmp = rnd(10);
X u.uhpmax += tmp;
X u.uhp += tmp;
X#ifdef SPELLS
X tmp = rnd(u.ulevel/2+1) + 1; /* M. Stephenson */
X u.uenmax += tmp;
X u.uen += tmp;
X#endif
X flags.botl = 1;
X }
X
X /* dispose of monster and make cadaver */
X x = mtmp->mx; y = mtmp->my;
X mondead(mtmp);
X tmp = mdat->mlet;
X if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */
X /* note: the dead minotaur will be on top of it! */
X mksobj_at(WAN_DIGGING, x, y);
X /* if(cansee(x,y)) atl(x,y,fobj->olet); */
X stackobj(fobj);
X } else
X#ifndef NOWORM
X if(tmp == 'w') {
X mksobj_at(WORM_TOOTH, x, y);
X stackobj(fobj);
X } else
X#endif
X#ifdef KAA
X if(tmp == '&') (void) mkobj_at(0, x, y);
X else
X if(stoned == FALSE && (!letter(tmp) || (!index("9&1", tmp) && !rn2(3)))) tmp = 0;
X if(dest & 2) {
X newsym(x,y);
X return;
X }
X#else
X if(!letter(tmp) || (!index("mw", tmp) && !rn2(3))) tmp = 0;
X#endif
X
X if(ACCESSIBLE(levl[x][y].typ)) /* might be mimic in wall or dead eel*/
X if(x != u.ux || y != u.uy) { /* might be here after swallowed */
X#ifdef KAA
X if(stoned) {
X register char typetmp;
X if(index(mlarge, tmp)) typetmp = ENORMOUS_ROCK;
X else typetmp = ROCK;
X mksobj_at(typetmp, x, y);
X if(cansee(x,y))
X atl(x,y,Hallucination ? rndobjsym() :
X objects[typetmp].oc_olet);
X } else if(index("NTVm&w",mdat->mlet) || rn2(5)) {
X#else
X if(index("NTVm&w",mdat->mlet) || rn2(5)) {
X#endif
X register struct obj *obj2 = mkobj_at(tmp,x,y);
X if(cansee(x,y))
X atl(x, y, Hallucination ? rndobjsym() : obj2->olet);
X stackobj(obj2);
X }
X }
X}
X
Xkludge(str,arg)
Xregister char *str,*arg;
X{
X if(Blind) {
X if(*str == '%') pline(str,"It");
X else pline(str,"it");
X } else pline(str,arg);
X}
X
Xrescham() /* force all chameleons to become normal */
X{
X register struct monst *mtmp;
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->cham) {
X mtmp->cham = 0;
X (void) newcham(mtmp, PM_CHAMELEON);
X }
X}
X
X#ifdef DGKMOD
X/* Let the chameleons change again -dgk */
Xrestartcham()
X{
X register struct monst *mtmp;
X
X for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if (mtmp->data->mlet == ':')
X mtmp->cham = 1;
X}
X#endif
X
Xnewcham(mtmp,mdat) /* make a chameleon look like a new monster */
X /* returns 1 if the monster actually changed */
Xregister struct monst *mtmp;
Xregister struct permonst *mdat;
X{
X register mhp, hpn, hpd;
X
X if(mdat == mtmp->data) return(0); /* still the same monster */
X#ifndef NOWORM
X if(mtmp->wormno) wormdead(mtmp); /* throw tail away */
X#endif
X hpn = mtmp->mhp;
X hpd = (mtmp->data->mlevel)*8; if(!hpd) hpd = 4;
X mhp = (mdat->mlevel)*8; if(!mhp) mhp = 4;
X
X /* new hp: same fraction of max as before */
X mtmp->mhp = (hpn*mhp)/hpd;
X if (mhp > hpd && mtmp->mhp < hpn) mtmp->mhp = 127;
X/* Not totally foolproof. A 2HD monster with 80 HP that changes into a 6HD
X monster that really should have 240 and actually should have 127, the
X maximum possible, will wind up having 113. */
X if (!mtmp->mhp) mtmp->mhp = 1;
X/* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
X 0HD creature will require this statement */
X mtmp->data = mdat;
X/* and the same for maximum hit points */
X hpn = mtmp->mhpmax;
X mtmp->mhpmax = (hpn*mhp)/hpd;
X if (mhp > hpd && mtmp->mhpmax < hpn) mtmp->mhp = 127;
X if (!mtmp->mhp) mtmp->mhp = 1;
X
X mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0;
X /* only snakes and scorpions can hide under things -dgk */
X /* also generated by GAN */
X mtmp->mhide = (mdat->mlet == 'S' || mdat->mlet == 's') ? 1 : 0;
X if (!mtmp->mhide) mtmp->mundetected = 0;
X#ifndef NOWORM
X if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp);
X /* perhaps we should clear mtmp->mtame here? */
X#endif
X unpmon(mtmp); /* necessary for 'I' and to force pmon */
X pmon(mtmp);
X return(1);
X}
X
Xmnexto(mtmp) /* Make monster mtmp next to you (if possible) */
Xstruct monst *mtmp;
X{
X extern coord enexto();
X coord mm;
X mm = enexto(u.ux, u.uy);
X mtmp->mx = mm.x;
X mtmp->my = mm.y;
X pmon(mtmp);
X}
X
Xishuman(mtmp) register struct monst *mtmp; {
X return(mtmp->data->mlet == '@');
X}
X
Xsetmangry(mtmp) register struct monst *mtmp; {
X if(!mtmp->mpeaceful) return;
X if(mtmp->mtame) return;
X mtmp->mpeaceful = 0;
X if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp));
X}
X
X/* not one hundred procent correct: now a snake may hide under an
X invisible object */
Xcanseemon(mtmp)
Xregister struct monst *mtmp;
X{
X return((!mtmp->minvis || See_invisible)
X && (!mtmp->mhide || !o_at(mtmp->mx,mtmp->my))
X && cansee(mtmp->mx, mtmp->my));
X}
X
Xdisturb(mtmp) /* awaken monsters while in the same room.
X * return a 1 if they have been woken.
X */
Xregister struct monst *mtmp;
X{
X /* wake up, or get out of here. */
X /* ettins are hard to surprise */
X /* Nymphs and Leprechauns do not easily wake up */
X if(cansee(mtmp->mx,mtmp->my) &&
X (!Stealth || (mtmp->data->mlet == 'e' && rn2(10))) &&
X (!index("NL",mtmp->data->mlet) || !rn2(50)) &&
X (Aggravate_monster || index("d1", mtmp->data->mlet)
X || (!rn2(7) && !mtmp->mimic))) {
X mtmp->msleep = 0;
X return(1);
X }
X if(Hallucination) pmon(mtmp);
X return(0);
X}
X
X#ifdef HARD
Xrestrap(mtmp) /* unwatched mimics and piercers may hide again,
X * if so, a 1 is returned.
X */
Xregister struct monst *mtmp;
X{
X if(mtmp->data->mlet == 'M' && !mtmp->mimic && !mtmp->cham
X && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my)
X && !rn2(3)) {
X mtmp->mimic = 1;
X mtmp->mappearance = (levl[mtmp->mx][mtmp->my].typ == DOOR) ? DOOR_SYM : '$';
X return(1);
X }
X
X if(mtmp->data->mlet == 'p' && !mtmp->cham
X && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my)
X && !rn2(3)) {
X
X if(levl[mtmp->mx][mtmp->my].typ == ROOM) {
X
X maketrap(mtmp->mx, mtmp->my, PIERC);
X mondead(mtmp);
X return(1);
X }
X }
X return(0);
X}
X#endif
END_OF_mon.c
if test 17706 -ne `wc -c <mon.c`; then
echo shar: \"mon.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f trap.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"trap.c\"
else
echo shar: Extracting \"trap.c\" \(19282 characters\)
sed "s/^X//" >trap.c <<'END_OF_trap.c'
X/* SCCS Id: @(#)trap.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* trap.c - version 1.0.3 */
X
X#include <stdio.h>
X#include "hack.h"
X
Xextern struct monst *makemon();
X#ifdef KAA
Xextern char *Xmonnam();
Xextern char *nomovemsg;
X#endif
X
Xchar vowels[] = "aeiou";
X
Xchar *traps[] = {
X "",
X " bear trap",
X "n arrow trap",
X " dart trap",
X " trapdoor",
X " teleportation trap",
X " pit",
X " sleeping gas trap",
X " piercer",
X " mimic"
X#ifdef NEWTRAPS
X ," magic trap"
X ," squeaky board"
X#endif
X#ifdef SPIDERS
X ," web"
X#endif
X#ifdef NEWCLASS
X ," spiked pit",
X " level teleporter"
X#endif
X#ifdef SPELLS
X ," anti-magic field"
X#endif
X#ifdef KAA
X ," rust trap"
X#endif
X};
X
Xstruct trap *
Xmaketrap(x,y,typ)
Xregister x,y,typ;
X{
X register struct trap *ttmp;
X
X ttmp = newtrap();
X ttmp->ttyp = typ;
X ttmp->tseen = 0;
X ttmp->once = 0;
X ttmp->tx = x;
X ttmp->ty = y;
X ttmp->ntrap = ftrap;
X ftrap = ttmp;
X return(ttmp);
X}
X
Xdotrap(trap) register struct trap *trap; {
X register int ttype = trap->ttyp;
X register struct monst *mtmp;
X
X nomul(0);
X if(trap->tseen && !rn2(5) && !(ttype == PIT
X#ifdef NEWCLASS
X || ttype == SPIKED_PIT
X#endif
X#ifdef SPELLS
X || ttype == ANTI_MAGIC
X#endif
X ))
X pline("You escape a%s.", traps[ttype]);
X else {
X trap->tseen = 1;
X switch(ttype) {
X case SLP_GAS_TRAP:
X pline("A cloud of gas puts you to sleep!");
X nomul(-rnd(25));
X break;
X case BEAR_TRAP:
X if(Levitation) {
X pline("You float over a bear trap.");
X break;
X }
X u.utrap = 4 + rn2(4);
X u.utraptype = TT_BEARTRAP;
X pline("A bear trap closes on your foot!");
X if(u.usym=='o') pline("You howl in anger!");
X break;
X case PIERC:
X deltrap(trap);
X if(mtmp=makemon(PM_PIERCER,u.ux,u.uy)) {
X pline("%s suddenly drops from the ceiling!", Xmonnam(mtmp));
X if(uarmh)
X pline("Its blow glances off your helmet.");
X else
X (void) thitu(3,d(4,6),"falling piercer");
X }
X break;
X case ARROW_TRAP:
X pline("An arrow shoots out at you!");
X if(!thitu(8,rnd(6),"arrow")){
X mksobj_at(ARROW, u.ux, u.uy);
X fobj->quan = 1;
X }
X break;
X case TRAPDOOR:
X if(!xdnstair) {
Xpline("A trap door in the ceiling opens and a rock falls on your head!");
Xif(uarmh) pline("Fortunately, you are wearing a helmet!");
X losehp(uarmh ? 2 : d(2,10),"falling rock");
X mksobj_at(ROCK, u.ux, u.uy);
X fobj->quan = 1;
X stackobj(fobj);
X if(Invisible) newsym(u.ux, u.uy);
X } else {
X register int newlevel = dlevel + 1;
X while(!rn2(4) && newlevel < 29)
X newlevel++;
X pline("A trap door opens up under you!");
X if(Levitation || u.ustuck) {
X pline("For some reason you don't fall in.");
X break;
X }
X fflush(stdout);
X goto_level(newlevel, FALSE);
X }
X break;
X case DART_TRAP:
X pline("A little dart shoots out at you!");
X if(thitu(7,rnd(3),"little dart")) {
X if(!rn2(6))
X poisoned("dart","poison dart");
X } else {
X mksobj_at(DART, u.ux, u.uy);
X fobj->quan = 1;
X }
X break;
X case TELEP_TRAP:
X if(trap->once) {
X deltrap(trap);
X newsym(u.ux,u.uy);
X vtele();
X } else {
X newsym(u.ux,u.uy);
X tele();
X }
X break;
X#ifdef KAA
X case RUST_TRAP:
X switch (rn2(5)) {
X case 0:
X pline("A gush of water hits you on the head!");
X if (uarmh) {
X if (uarmh->rustfree)
X pline("Your helmet is not affected!");
X else {
X pline("Your helmet rusts!");
X uarmh->spe--;
X }
X }
X break;
X case 1:
X pline("A gush of water hits your left arm!");
X if (uarms) {
X pline("Your shield is not affected!");
X break;
X }
X if (uwep->otyp == TWO_HANDED_SWORD) goto two_hand;
X /* Two goto statements in a row--aaarrrgggh! */
X glovecheck: if(uarmg) pline("Your gloves are not affected!");
X break;
X case 2:
X pline("A gush of water hits your right arm!");
X two_hand: corrode_weapon();
X goto glovecheck;
X default:
X pline("A gush of water hits you!");
X if (uarm)
X if (uarm->rustfree ||
X uarm->otyp >= STUDDED_LEATHER_ARMOR)
X pline("Your %s not affected!",
X aobjnam(uarm,"are"));
X else {
X pline("Your %s!",aobjnam(uarm,"corrode"));
X uarm->spe--;
X }
X }
X break;
X#endif
X case PIT:
X if (Levitation || index("EyBfk'&",u.usym)) {
X pline("A pit opens up under you!");
X pline("You don't fall in!");
X break;
X }
X pline("You fall into a pit!");
X u.utrap = rn1(6,2);
X u.utraptype = TT_PIT;
X losehp(rnd(6),"fall into a pit");
X selftouch("Falling, you");
X break;
X#ifdef NEWCLASS
X case SPIKED_PIT:
X if (Levitation || index("EyBfk'&",u.usym)) {
X pline("A pit opens up under you!");
X pline("You don't fall in!");
X pline("There are spikes in that pit!!!");
X break;
X }
X pline("You fall into a pit!");
X pline("You land on a set of sharp iron spikes!");
X u.utrap = rn1(6,2);
X u.utraptype = TT_PIT;
X losehp(rnd(10),"fall onto iron spikes");
X if(!rn2(6)) poisoned("spikes","poison spikes");
X selftouch("Falling, you");
X break;
X case LEVEL_TELEP:
X if (!Blind) pline("You are momentarily blinded by a flash of light");
X else pline("You are momentarily disoriented.");
X deltrap(trap);
X newsym(u.ux,u.uy);
X level_tele();
X break;
X#endif
X#ifdef SPELLS
X case ANTI_MAGIC:
X pline("You feel your magical energy drain away!");
X u.uen -= (rnd(u.ulevel) + 1);
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 break;
X#endif
X#ifdef NEWTRAPS
X case MGTRP:
X /* A magic trap. */
X domagictrap();
X break;
X case SQBRD: {
X#include "edog.h"
X register struct monst *mtmp = fmon;
X /* Stepped on a squeaky board. */
X pline("A board underfoot gives off a loud squeak!");
X /* Wake up nearby monsters. */
X while(mtmp) {
X if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
X if(mtmp->msleep)
X mtmp->msleep = 0;
X if(mtmp->mtame)
X EDOG(mtmp)->whistletime = moves;
X }
X mtmp = mtmp->nmon;
X }
X }
X break;
X#endif
X#ifdef SPIDERS
X case WEB:
X
X /* Our luckless adventurer has stepped into a web. */
X
X pline("You've stumbled into a spider web!");
X u.utraptype = TT_WEB;
X
X /* Time stuck in the web depends on your strength. */
X
X if (u.ustr == 3) u.utrap = rn1(6,6);
X else if (u.ustr < 6) u.utrap = rn1(6,4);
X else if (u.ustr < 9) u.utrap = rn1(4,4);
X else if (u.ustr < 12) u.utrap = rn1(4,2);
X else if (u.ustr < 15) u.utrap = rn1(2,2);
X else if (u.ustr < 18) u.utrap = rnd(2);
X else if (u.ustr < 69) u.utrap = 1;
X else {
X u.utrap = 0;
X pline("You tear through the web!");
X deltrap(trap);
X }
X break;
X#endif
X default:
X impossible("You hit a trap of type %u", trap->ttyp);
X }
X }
X}
X
Xmintrap(mtmp) register struct monst *mtmp; {
X register struct trap *trap = t_at(mtmp->mx, mtmp->my);
X register int wasintrap = mtmp->mtrapped;
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#ifdef DGK
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#else
X int in_sight = cansee(mtmp->mx,mtmp->my);
X#endif
X extern char mlarge[];
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(index(mlarge, mtmp->data->mlet)) {
X if(in_sight)
X pline("%s is caught in a bear trap!",
X Monnam(mtmp));
X else
X if(mtmp->data->mlet == 'o')
X pline("You hear the roaring of an angry bear!");
X mtmp->mtrapped = 1;
X }
X break;
X#ifdef KAA
X case RUST_TRAP:
X if(in_sight)
X pline("A gush of water hits %s!",monnam(mtmp));
X break;
X#endif
X case PIT:
X#ifdef NEWCLASS
X case SPIKED_PIT:
X#endif
X /* there should be a mtmp/data -> floating */
X if(!index("EywBIfk'& ", mtmp->data->mlet)) { /* ab */
X mtmp->mtrapped = 1;
X if(in_sight)
X pline("%s falls into a pit!", Monnam(mtmp));
X }
X break;
X case SLP_GAS_TRAP:
X if(!mtmp->msleep && !mtmp->mfroz) {
X mtmp->msleep = 1;
X if(in_sight)
X pline("%s suddenly falls asleep!",
X Monnam(mtmp));
X }
X break;
X case TELEP_TRAP:
X#ifdef NEWCLASS
X case LEVEL_TELEP:
X#endif
X rloc(mtmp);
X if(in_sight && !cansee(mtmp->mx,mtmp->my))
X pline("%s suddenly disappears!",
X Monnam(mtmp));
X break;
X case ARROW_TRAP:
X if(in_sight)
X pline("%s is hit by an arrow!", Monnam(mtmp));
X mtmp->mhp -= 3;
X break;
X case DART_TRAP:
X if(in_sight)
X pline("%s is hit by a dart!", Monnam(mtmp));
X mtmp->mhp -= 2;
X /* not mondied here !! */
X break;
X case TRAPDOOR:
X if(!xdnstair) {
X mtmp->mhp -= 10;
X if(in_sight)
Xpline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
X break;
X }
X if(!index("EywBIfk", mtmp->data->mlet)){
X fall_down(mtmp);
X if(in_sight)
X pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
X return(2); /* no longer on this level */
X }
X break;
X case PIERC:
X break;
X#ifdef NEWTRAPS
X case MGTRP:
X /* A magic trap. Monsters immune. */
X break;
X case SQBRD: {
X register struct monst *ztmp = fmon;
X
X if(index("EyBIfk", mtmp->data->mlet)) break;
X /* Stepped on a squeaky board. */
X if (in_sight)
X pline("%s steps on a squeaky board.", Monnam(mtmp));
X else
X pline("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#endif
X#ifdef SPIDERS
X case WEB:
X /* Monster in a web. */
X /* in_sight check and confused bear by Eric Backus */
X if(mtmp->data->mlet != 's') {
X if(in_sight)
X pline("%s is caught in a web!", Monnam(mtmp));
X else
X if(mtmp->data->mlet == 'o')
X pline("You hear the roaring of a confused bear!");
X mtmp->mtrapped = 1;
X }
X break;
X#endif
X#ifdef SPELLS
X case ANTI_MAGIC: break;
X#endif
X default:
X impossible("Some monster encountered a strange trap of type %d.",tt);
X }
X }
X return(mtmp->mtrapped);
X}
X
Xselftouch(arg) char *arg; {
X if(uwep && uwep->otyp == DEAD_COCKATRICE){
X pline("%s touch the dead cockatrice.", arg);
X pline("You turn to stone.");
X pline("You die...");
X killer = objects[uwep->otyp].oc_name;
X done("died");
X }
X}
X
Xfloat_up(){
X if(u.utrap) {
X if(u.utraptype == TT_PIT) {
X u.utrap = 0;
X pline("You float up, out of the pit!");
X } else {
X pline("You float up, only your leg is still stuck.");
X }
X } else
X if (Hallucination)
X pline("Oh wow! You're floating in the air!");
X else
X pline("You start to float in the air!");
X}
X
Xfloat_down(){
X register struct rm *tmpr;
X register struct trap *trap;
X
X /* check for falling into pool - added by GAN 10/20/86 */
X if(IS_POOL(levl[u.ux][u.uy].typ) && !Levitation)
X drown();
X
X pline("You float gently to the ground.");
X if(trap = t_at(u.ux,u.uy))
X switch(trap->ttyp) {
X case PIERC:
X break;
X case TRAPDOOR:
X if(!xdnstair || u.ustuck) break;
X /* fall into next case */
X default:
X dotrap(trap);
X }
X pickup(1);
X}
X
X#include "mkroom.h"
X
Xvtele() {
X register struct mkroom *croom;
X
X for(croom = &rooms[0]; croom->hx >= 0; croom++)
X if(croom->rtype == VAULT) {
X register 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
Xtele() {
X extern coord getpos();
X coord cc;
X register int nux,nuy;
X
X if(Teleport_control) {
X#ifdef KAA
X if (multi < 0 && (!nomovemsg ||
X !strncmp(nomovemsg,"You awake", 9) ||
X !strncmp(nomovemsg,"You regain con", 15) ||
X !strncmp(nomovemsg,"You are consci", 15)))
X
X pline("Being unconscious, you cannot control your teleport.");
X else {
X#endif
X
X pline("To what position do you want to be teleported?");
X cc = getpos(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#ifdef KAA
X }
X#endif
X }
X do {
X nux = rnd(COLNO-1);
X nuy = rn2(ROWNO);
X } while(!teleok(nux, nuy));
X teleds(nux, nuy);
X}
X
Xteleds(nux, nuy)
Xregister int nux,nuy;
X{
X if(Punished) unplacebc();
X unsee();
X u.utrap = 0;
X u.ustuck = 0;
X u.ux = nux;
X u.uy = nuy;
X setsee();
X if(Punished) placebc(1);
X if(u.uswallow){
X u.uswldtim = u.uswallow = 0;
X docrt();
X }
X nomul(0);
X if(IS_POOL(levl[nux][nuy].typ) && !Levitation)
X drown();
X (void) inshop();
X pickup(1);
X if(!Blind) read_engr_at(u.ux,u.uy);
X}
X
Xteleok(x,y) register int x,y; { /* might throw him into a POOL
X * removed by GAN 10/20/86
X */
X#ifdef STUPID
X boolean tmp1, tmp2, tmp3;
X tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y);
X tmp2 = !sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y);
X tmp3 = !(IS_POOL(levl[x][y].typ) && !Levitation);
X return(tmp1 && tmp2 && tmp3);
X#else
X return( isok(x,y) && !IS_ROCK(levl[x][y].typ) && !m_at(x,y) &&
X !sobj_at(ENORMOUS_ROCK,x,y) && !t_at(x,y) &&
X !(IS_POOL(levl[x][y].typ) && !Levitation)
X );
X#endif
X /* Note: gold is permitted (because of vaults) */
X}
X
Xdotele() {
X extern char pl_character[];
X
X if((!index("LNt",u.usym)) &&
X#ifdef WIZARD
X !wizard &&
X#endif
X (!Teleportation || u.ulevel < 6 ||
X (pl_character[0] != 'W' && u.ulevel < 10))) {
X pline("You are not able to teleport at will.");
X return(0);
X }
X if(u.uhunger <= 100 || u.ustr < 6) {
X pline("You miss the strength for a teleport spell.");
X#ifdef WIZARD
X if(!wizard)
X#endif
X return(1);
X }
X tele();
X morehungry(100);
X return(1);
X}
X
Xplacebc(attach) int attach; {
X if(!uchain || !uball){
X impossible("Where are your chain and ball??");
X return;
X }
X uball->ox = uchain->ox = u.ux;
X uball->oy = uchain->oy = 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
Xunplacebc(){
X if(!carried(uball)){
X freeobj(uball);
X unpobj(uball);
X }
X freeobj(uchain);
X unpobj(uchain);
X}
X
Xlevel_tele() {
Xregister int newlevel;
X if(Teleport_control) {
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 DGKMOD
X newlevel = rn2(5) ? 5 + rn2(20) : 30;
X#else
X newlevel = 5 + rn2(20); /* 5 - 24 */
X#endif
X if(dlevel == newlevel)
X if(!xdnstair) newlevel--; else newlevel++;
X }
X if(newlevel >= 30) {
X if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;
X pline("You arrive at the center of the earth ...");
X pline("Unfortunately it is here that hell is located.");
X#ifdef DGK
X fflush(stdout);
X#endif
X if(Fire_resistance) {
X pline("But the fire doesn't seem to harm you.");
X } else {
X pline("You burn to a crisp.");
X pline("You die...");
X dlevel = maxdlevel = newlevel;
X killer = "visit to hell";
X done("burned");
X }
X }
X if(newlevel < 0) {
X if(newlevel <= -10) {
X pline("You arrive in heaven.");
X pline("\"You are here a bit early, but we'll let you in.\"");
X killer = "visit to heaven";
X done("died");
X }
X newlevel = 0;
X pline("You are now high above the clouds ...");
X if(Levitation) {
X pline("You float gently down to earth.");
X done("escaped");
X }
X pline("Unfortunately, you don't know how to fly.");
X pline("You fall down a few thousand feet and break your neck.");
X pline("You die...");
X dlevel = 0;
X killer = "fall";
X done("died");
X }
X
X goto_level(newlevel, FALSE); /* calls done("escaped") if newlevel==0 */
X}
X
X#ifdef NEWTRAPS
X
Xdomagictrap()
X{
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 pline("You are momentarily blinded by a flash of light!");
X Blind += rn1(5,10);
X seeoff(0);
X } else
X pline("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 pline("You are uninjured.");
X else {
X num = rnd(6);
X u.uhpmax -= num;
X losehp(num,"a burst of flame");
X break;
X }
X }
X
X /* odd feelings */
X case 13: pline("A shiver runs up and down your spine!");
X break;
X case 14: pline("You hear distant howling.");
X break;
X case 15: pline("You suddenly yearn for your distant homeland.");
X break;
X case 16: pline("Your pack shakes violently!");
X break;
X
X /* very occasionally something nice happens. */
X
X case 19:
X /* tame nearby monsters */
X { register int i,j;
X register boolean confused = (Confusion != 0);
X register int bd = confused ? 5 : 1;
X register struct monst *mtmp;
X
X /* below pline added by GAN 10/30/86 */
X pline("You feel charismatic.");
X for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
X if(mtmp = m_at(u.ux+i, u.uy+j))
X (void) tamedog(mtmp, (struct obj *) 0);
X break;
X }
X
X case 20:
X /* uncurse stuff */
X { register struct obj *obj;
X register boolean confused = (Confusion != 0);
X
X /* below plines added by GAN 10/30/86 */
X if (confused)
X if (Hallucination)
X pline("You feel the power of the Force against you!");
X else
X pline("You feel like you need some help.");
X else
X if (Hallucination)
X pline("You feel in touch with the Universal Oneness.");
X else
X pline("You feel like someone is helping you.");
X for(obj = invent; obj ; obj = obj->nobj)
X if(obj->owornmask)
X obj->cursed = confused;
X if(Punished && !confused) {
X Punished = 0;
X freeobj(uchain);
X unpobj(uchain);
X free((char *) uchain);
X uball->spe = 0;
X uball->owornmask &= ~W_BALL;
X uchain = uball = (struct obj *) 0;
X }
X break;
X }
X default: break;
X }
X}
X
X#endif /* NEWTRAPS /**/
X
X
Xdrown()
X{
X pline("You fall into a pool!");
X pline("You can't swim!");
X if(
X#ifdef WIZARD
X wizard ||
X#endif
X rn2(3) < u.uluck+2) {
X /* most scrolls become unreadable */
X register struct obj *obj;
X
X for(obj = invent; obj; obj = obj->nobj)
X if(obj->olet == SCROLL_SYM && rn2(12) > u.uluck)
X obj->otyp = SCR_BLANK_PAPER;
X /* we should perhaps merge these scrolls ? */
X
X pline("You attempt a teleport spell."); /* utcsri!carroll */
X (void) dotele();
X if(!IS_POOL(levl[u.ux][u.uy].typ)) return;
X }
X pline("You drown.");
X pline("You die...");
X killer = "pool of water";
X done("drowned");
X}
END_OF_trap.c
if test 19282 -ne `wc -c <trap.c`; then
echo shar: \"trap.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 5 \(of 16\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 16 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0