games-request@tekred.TEK.COM (07/28/87)
Submitted by: mike@genat.UUCP (Mike Stephenson) Comp.sources.games: Volume 2, Issue 3 Archive-name: nethack/Part03 #! /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 3 (of 16)." # Contents: hack.c wield.c zap.c # Wrapped by billr@tekred on Tue Jul 28 09:49:22 1987 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f hack.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"hack.c\" else echo shar: Extracting \"hack.c\" \(24139 characters\) sed "s/^X//" >hack.c <<'END_OF_hack.c' X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* hack.c - version 1.0.3 */ X X#include <stdio.h> X#include "hack.h" X#ifdef UNIX Xstatic char SCCS_Id[] = "@(#)hack.c 1.3\t87/07/14"; X#endif Xextern char news0(); Xextern char *nomovemsg; Xextern char *exclam(); Xextern struct obj *addinv(); Xextern boolean hmon(); X X/* called on movement: X 1. when throwing ball+chain far away X 2. when teleporting X 3. when walking out of a lit room X */ Xunsee() { X register x,y; X register struct rm *lev; X X/* X if(u.udispl){ X u.udispl = 0; X newsym(u.udisx, u.udisy); X } X*/ X#ifndef QUEST X if(seehx){ X seehx = 0; X } else X#endif X for(x = u.ux-1; x < u.ux+2; x++) X for(y = u.uy-1; y < u.uy+2; y++) { X if(!isok(x, y)) continue; X lev = &levl[x][y]; X#ifdef DGK X if(!lev->lit && lev->scrsym == symbol.room) { X#else X if(!lev->lit && lev->scrsym == '.') { X#endif X lev->scrsym =' '; X lev->new = 1; X on_scr(x,y); X } X } X} X X/* called: X in apply.c: seeoff(0) - when taking a picture of yourself X in do.c: seeoff(0) - blind after drinking potion X in do.c: seeoff(1) - go up or down the stairs X in eat.c: seeoff(0) - blind after eating rotten food X in mhitu.c: seeoff(0) - blinded by a yellow light X in mon.c: seeoff(1) - swallowed X in potion.c: seeoff(0) - quaffing or sniffing a potion of blindness X in spell.c: seeoff(0) - due to a cursed spellbook X in trap.c: seeoff(1) - fall through trapdoor X in wizard.c: seeoff(0) - hit by a cream pie. X */ Xseeoff(mode) /* 1 to redo @, 0 to leave them */ X{ /* 1 means misc movement, 0 means blindness */ X register x,y; X register struct rm *lev; X X if(u.udispl && mode){ X u.udispl = 0; X levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy); X } X#ifndef QUEST X if(seehx) { X seehx = 0; X } else X#endif X if(!mode) { X for(x = u.ux-1; x < u.ux+2; x++) X for(y = u.uy-1; y < u.uy+2; y++) { X if(!isok(x, y)) continue; X lev = &levl[x][y]; X#ifdef DGK X if(!lev->lit && lev->scrsym == symbol.room) X#else X if(!lev->lit && lev->scrsym == '.') X#endif X lev->seen = 0; X } X } X} X Xstatic Xmoverock() { X register xchar rx, ry; X register struct obj *otmp; X register struct trap *ttmp; X X while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) { X rx = u.ux+2*u.dx; X ry = u.uy+2*u.dy; X nomul(0); X if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) && X (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) && X !sobj_at(ENORMOUS_ROCK, rx, ry)) { X if(m_at(rx,ry)) { X pline("You hear a monster behind the rock."); X pline("Perhaps that's why you cannot move it."); X goto cannot_push; X } X if(ttmp = t_at(rx,ry)) X switch(ttmp->ttyp) { X case PIT: X pline("You push the rock into a pit!"); X deltrap(ttmp); X delobj(otmp); X pline("It completely fills the pit!"); X continue; X case TELEP_TRAP: X pline("You push the rock and suddenly it disappears!"); X delobj(otmp); X continue; X } X if(levl[rx][ry].typ == POOL) { X levl[rx][ry].typ = ROOM; X mnewsym(rx,ry); X prl(rx,ry); X pline("You push the rock into the water."); X pline("Now you can cross the water!"); X delobj(otmp); X continue; X } X otmp->ox = rx; X otmp->oy = ry; X /* pobj(otmp); */ X if(cansee(rx,ry)) atl(rx,ry,otmp->olet); X if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy); X X { static long lastmovetime; X /* note: this var contains garbage initially and X after a restore */ X if(moves > lastmovetime+2 || moves < lastmovetime) X pline("With great effort you move the enormous rock."); X lastmovetime = moves; X } X } else { X pline("You try to move the enormous rock, but in vain."); X cannot_push: X#ifdef KAA X if (u.usym=='9') { X# ifdef DGKMOD X if(!flags.pickup) X pline("You easily can push it aside."); X else X# endif X pline("However, you easily can pick it up."); X break; X } X#endif X if((!invent || inv_weight()+90 <= 0) && X (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ) X && IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){ X pline("However, you can squeeze yourself into a small opening."); X break; X } else X return (-1); X } X } X return (0); X} X Xdomove() X{ X register struct monst *mtmp; X register struct rm *tmpr,*ust; X struct trap *trap; X register struct obj *otmp; X X u_wipe_engr(rnd(5)); X X if(inv_weight() > 0){ X pline("You collapse under your load."); X nomul(0); X return; X } X if(u.uswallow) { X u.dx = u.dy = 0; X u.ux = u.ustuck->mx; X u.uy = u.ustuck->my; X } else { X if(Confusion) { X do { X confdir(); X } while(!isok(u.ux+u.dx, u.uy+u.dy) || X IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ)); X } X if(!isok(u.ux+u.dx, u.uy+u.dy)){ X nomul(0); X return; X } X } X X ust = &levl[u.ux][u.uy]; X u.ux0 = u.ux; X u.uy0 = u.uy; X if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen) X nomul(0); X if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx || X u.uy+u.dy != u.ustuck->my)) { X if(dist(u.ustuck->mx, u.ustuck->my) > 2){ X /* perhaps it fled (or was teleported or ... ) */ X u.ustuck = 0; X } else { X if(Blind) pline("You cannot escape from it!"); X else pline("You cannot escape from %s!", X monnam(u.ustuck)); X nomul(0); X return; X } X } X if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) { X /* attack monster */ X X#ifdef SAFE_ATTACK X /* Don't attack if you're running */ X if (flags.run && !mtmp->mimic X && (Blind ? Telepat : (!mtmp->minvis || See_invisible))) { X nomul(0); X flags.move = 0; X return; X } X#endif X nomul(0); X gethungry(); X if(multi < 0) return; /* we just fainted */ X X /* try to attack; note that it might evade */ X if(attack(u.uswallow ? u.ustuck : mtmp)) X return; X } X /* not attacking an animal, so we try to move */ X if(u.utrap) { X if(u.utraptype == TT_PIT) { X pline("You are still in a pit."); X u.utrap--; X } else { X pline("You are caught in a beartrap."); X if((u.dx && u.dy) || !rn2(5)) u.utrap--; X } X return; X } X tmpr = &levl[u.ux+u.dx][u.uy+u.dy]; X if(IS_ROCK(tmpr->typ) || X (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){ X flags.move = 0; X nomul(0); X return; X } X if(moverock() < 0) return; X if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) && X IS_ROCK(levl[u.ux+u.dx][u.uy].typ) && X invent && inv_weight()+40 > 0) { X pline("You are carrying too much to get through."); X nomul(0); X return; X } X if(Punished && X DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){ X if(carried(uball)) { X movobj(uchain, u.ux, u.uy); X goto nodrag; X } X X if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){ X /* leave ball, move chain under/over ball */ X movobj(uchain, uball->ox, uball->oy); X goto nodrag; X } X X if(inv_weight() + (int) uball->owt/2 > 0) { X pline("You cannot %sdrag the heavy iron ball.", X invent ? "carry all that and also " : ""); X nomul(0); X return; X } X X movobj(uball, uchain->ox, uchain->oy); X unpobj(uball); /* BAH %% */ X uchain->ox = u.ux; X uchain->oy = u.uy; X nomul(-2); X nomovemsg = ""; X nodrag: ; X } X u.ux += u.dx; X u.uy += u.dy; X if(flags.run) { X if(tmpr->typ == DOOR || X (xupstair == u.ux && yupstair == u.uy) || X (xdnstair == u.ux && ydnstair == u.uy) X#ifdef FOUNTAINS X || IS_FOUNTAIN(levl[u.ux][u.uy].typ) X#endif X#ifdef NEWCLASS X || IS_THRONE(levl[u.ux][u.uy].typ) X#endif X ) X nomul(0); X } X X if(tmpr->typ == POOL && !Levitation) X drown(); /* not necessarily fatal */ X X/* X if(u.udispl) { X u.udispl = 0; X newsym(u.ux0,u.uy0); X } X*/ X if(!Blind) { X#ifdef QUEST X setsee(); X#else X if(ust->lit) { X if(tmpr->lit) { X if(tmpr->typ == DOOR) X prl1(u.ux+u.dx,u.uy+u.dy); X else if(ust->typ == DOOR) X nose1(u.ux0-u.dx,u.uy0-u.dy); X } else { X unsee(); X prl1(u.ux+u.dx,u.uy+u.dy); X } X } else { X if(tmpr->lit) setsee(); X else { X prl1(u.ux+u.dx,u.uy+u.dy); X if(tmpr->typ == DOOR) { X if(u.dy) { X prl(u.ux-1,u.uy); X prl(u.ux+1,u.uy); X } else { X prl(u.ux,u.uy-1); X prl(u.ux,u.uy+1); X } X } X } X nose1(u.ux0-u.dx,u.uy0-u.dy); X } X#endif /* QUEST /**/ X } else { X pru(); X } X if(!flags.nopick) pickup(1); X if(trap) dotrap(trap); /* fall into pit, arrow trap, etc. */ X (void) inshop(); X if(!Blind) read_engr_at(u.ux,u.uy); X} X Xmovobj(obj, ox, oy) Xregister struct obj *obj; Xregister int ox, oy; X{ X /* Some dirty programming to get display right */ X freeobj(obj); X unpobj(obj); X obj->nobj = fobj; X fobj = obj; X obj->ox = ox; X obj->oy = oy; X} X Xdopickup(){ X /* uswallow case added by GAN 01/29/87 */ X if(u.uswallow) { X pline("You pick up %s's tongue.",monnam(u.ustuck)); X pline("But it's kind of slimy, so you drop it."); X return(1); X } X if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) { X pline("There is nothing here to pick up."); X return(0); X } X if(Levitation) { X pline("You cannot reach the floor."); X return(1); X } X pickup(0); X return(1); X} X Xpickup(all) X{ X register struct gold *gold; X register struct obj *obj, *obj2; X register int wt; X char buf[BUFSZ]; X register char *ip; X register char sym; X register int oletct = 0, iletct = 0; X char olets[20], ilets[20]; X X if(Levitation) return; X#ifdef DGKMOD X if (all && !flags.pickup) { X int ct = 0; X X for (obj = fobj; obj; obj = obj->nobj) X if (obj->ox == u.ux && obj->oy == u.uy) X if (!Punished || obj != uchain) X ct++; X /* If gold is the only thing here, pick it up. X */ X if (!ct && g_at(u.ux, u.uy)) { X if (flags.run) nomul(0); X while (gold = g_at(u.ux,u.uy)) { X pline("%ld gold piece%s.", gold->amount, X plur(gold->amount)); X u.ugold += gold->amount; X flags.botl = 1; X freegold(gold); X } X if (Invisible) newsym(u.ux,u.uy); X } X X /* If there are objects here, take a look. X */ X if (ct) { X if (flags.run) X nomul(0); X nscr(); X if (ct < 5) X dolook(); X else X pline("There are several objects here."); X } X return; X } X#endif X while(gold = g_at(u.ux,u.uy)) { X pline("%ld gold piece%s.", gold->amount, plur(gold->amount)); X u.ugold += gold->amount; X flags.botl = 1; X freegold(gold); X if(flags.run) nomul(0); X if(Invisible) newsym(u.ux,u.uy); X } X /* check for more than one object */ X if(!all) { X register int ct = 0; X X for(obj = fobj; obj; obj = obj->nobj) X if(obj->ox == u.ux && obj->oy == u.uy) ct++; X if(g_at(u.ux,u.uy)) X ct++; X if(ct < 2) X all++; X else X pline("There are several objects here."); X } X X /* added by GAN 10/24/86 to allow selective picking up */ X if(!all) { X register struct obj *otmp = fobj; X X if(g_at(u.ux,u.uy)) ilets[iletct++] = '$'; X ilets[iletct] = 0; X while(otmp) { X if(!index(ilets, otmp->olet) && X otmp->ox == u.ux && otmp->oy == u.uy) { X ilets[iletct++] = otmp->olet; X ilets[iletct] = 0; X } X otmp = otmp->nobj; X } X if(iletct == 1) X strcpy(buf,ilets); X else { X ilets[iletct++] = ' '; X ilets[iletct++] = 'a'; X ilets[iletct++] = 'A'; X ilets[iletct] = 0; X X if(iletct = 3) X pline("What kinds of thing do you want to pick up? [%s]", ilets); X getlin(buf); X if(buf[0] == '\033') { X clrlin(); X return(0); X } X } X ip = buf; X olets[0] = 0; X while(sym = *ip++){ X /* new A function (selective all) added by X * GAN 01/09/87 X */ X if(sym == 'A') { X for(oletct = 0; ilets[oletct] != ' '; oletct++) X olets[oletct] = ilets[oletct]; X olets[oletct] = 0; X break; X } X if(sym == ' ') continue; X if(sym == 'a') all++; else X if(index(ilets, sym)){ X if(!index(olets, sym)){ X olets[oletct++] = sym; X olets[oletct] = 0; X } X } X else pline("There are no %c's here.", sym); X } X } X X if(all || index(olets,'$')) X while(gold = g_at(u.ux,u.uy)) { X pline("%ld gold piece%s.", gold->amount, X plur(gold->amount)); X u.ugold += gold->amount; X flags.botl = 1; X freegold(gold); X if(flags.run) nomul(0); X if(Invis) newsym(u.ux,u.uy); X } X X X for(obj = fobj; obj; obj = obj2) { X obj2 = obj->nobj; /* perhaps obj will be picked up */ X if(obj->ox == u.ux && obj->oy == u.uy) { X if(flags.run) nomul(0); X X if(!all) { X char c; X X if(!index(olets,obj->olet)) continue; X X pline("Pick up %s ? [ynaq]", doname(obj)); X while(!index("ynaq ", (c = readchar()))) X bell(); X if(c == 'q') return; X if(c == 'n') continue; X if(c == 'a') all = 1; X } X X if(obj->otyp == DEAD_COCKATRICE && !uarmg && u.usym != 'c') { X pline("Touching the dead cockatrice is a fatal mistake."); X pline("You turn to stone."); X pline("You die..."); X killer = "cockatrice cadaver"; X done("died"); X } X X if(obj->otyp == SCR_SCARE_MONSTER){ X if(!obj->spe) obj->spe = 1; X else { X /* Note: perhaps the 1st pickup failed: you cannot X carry anymore, and so we never dropped it - X lets assume that treading on it twice also X destroys the scroll */ X pline("The scroll turns to dust as you pick it up."); X#ifdef KAA X if(!(objects[SCR_SCARE_MONSTER].oc_name_known) && X !(objects[SCR_SCARE_MONSTER].oc_uname)) X docall(obj); X#endif X delobj(obj); X continue; X } X } X X /* do not pick up uchain */ X if(Punished && obj == uchain) X continue; X X X wt = inv_weight() + obj->owt; X if(wt > 0) { X if(obj->quan > 1) { X /* see how many we can lift */ X extern struct obj *splitobj(); X int savequan = obj->quan; X int iw = inv_weight(); X int qq; X for(qq = 1; qq < savequan; qq++){ X obj->quan = qq; X if(iw + weight(obj) > 0) X break; X } X obj->quan = savequan; X qq--; X /* we can carry qq of them */ X if(!qq) goto too_heavy; X pline("You can only carry %s of the %s lying here.", X (qq == 1) ? "one" : "some", X doname(obj)); X (void) splitobj(obj, qq); X /* note: obj2 is set already, so well never X * encounter the other half; if it should be X * otherwise then write X * obj2 = splitobj(obj,qq); X */ X goto lift_some; X } X too_heavy: X pline("There %s %s here, but %s.", X (obj->quan == 1) ? "is" : "are", X doname(obj), X !invent ? "it is too heavy for you to lift" X /* There is no such word as "anymore". KAA */ X : "you cannot carry any more"); X break; X } X lift_some: X if(inv_cnt() >= 52) { X pline("Your knapsack cannot accomodate any more items."); X break; X } X if(wt > -5) pline("You have a little trouble lifting"); X freeobj(obj); X if(Invisible) newsym(u.ux,u.uy); X addtobill(obj); /* sets obj->unpaid if necessary */ X { int pickquan = obj->quan; X int mergquan; X#ifdef KAA X if(!Blind) if(obj->olet != WEAPON_SYM) obj->dknown = 1; X#else X if(!Blind) obj->dknown = 1; /* this is done by prinv(), X but addinv() needs it already for merging */ X#endif X obj = addinv(obj); /* might merge it with other objects */ X mergquan = obj->quan; X obj->quan = pickquan; /* to fool prinv() */ X prinv(obj); X obj->quan = mergquan; X } X } X } X} X X/* stop running if we see something interesting */ X/* turn around a corner if that is the only way we can proceed */ X/* do not turn left or right twice */ Xlookaround(){ Xregister x,y,i,x0,y0,m0,i0 = 9; Xregister int corrct = 0, noturn = 0; Xregister struct monst *mtmp; X#ifdef lint X /* suppress "used before set" message */ X x0 = y0 = 0; X#endif X if(Blind || flags.run == 0) return; X if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return; X#ifdef QUEST X if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop; X#endif X for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ X if(x == u.ux && y == u.uy) continue; X if(!levl[x][y].typ) continue; X if((mtmp = m_at(x,y)) && !mtmp->mimic && X (!mtmp->minvis || See_invisible)){ X if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy)) X goto stop; X } else mtmp = 0; /* invisible M cannot influence us */ X if(x == u.ux-u.dx && y == u.uy-u.dy) continue; X#ifdef DGK X { X register uchar sym = levl[x][y].scrsym; X X if (sym == symbol.vwall || sym == symbol.hwall X || sym == symbol.room || sym == ' ' || IS_CORNER(sym)) X continue; X else if (sym == symbol.door) { X if(x != u.ux && y != u.uy) continue; X if(flags.run != 1) goto stop; X goto corr; X } else if (sym == symbol.corr) { X corr: X if(flags.run == 1 || flags.run == 3) { X i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); X if(i > 2) continue; X if(corrct == 1 && DIST(x,y,x0,y0) != 1) X noturn = 1; X if(i < i0) { X i0 = i; X x0 = x; X y0 = y; X m0 = mtmp ? 1 : 0; X } X } X corrct++; X continue; X } else if (sym == '^') { X if(flags.run == 1) goto corr; /* if you must */ X if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; X continue; X } else { /* e.g. objects or trap or stairs */ X if(flags.run == 1) goto corr; X if(mtmp) continue; /* d */ X } X stop: X nomul(0); X return; X } X#else X switch(levl[x][y].scrsym){ X case '|': X case '-': X case '.': X case ' ': X break; X case '+': X if(x != u.ux && y != u.uy) break; X if(flags.run != 1) goto stop; X /* fall into next case */ X case CORR_SYM: X corr: X if(flags.run == 1 || flags.run == 3) { X i = DIST(x,y,u.ux+u.dx,u.uy+u.dy); X if(i > 2) break; X if(corrct == 1 && DIST(x,y,x0,y0) != 1) X noturn = 1; X if(i < i0) { X i0 = i; X x0 = x; X y0 = y; X m0 = mtmp ? 1 : 0; X } X } X corrct++; X break; X case '^': X if(flags.run == 1) goto corr; /* if you must */ X if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; X break; X default: /* e.g. objects or trap or stairs */ X if(flags.run == 1) goto corr; X if(mtmp) break; /* d */ X stop: X nomul(0); X return; X } X#endif X } X#ifdef QUEST X if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop; X#endif X if(corrct > 1 && flags.run == 2) goto stop; X if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 && X (corrct == 1 || (corrct == 2 && i0 == 1))) { X /* make sure that we do not turn too far */ X if(i0 == 2) { X if(u.dx == y0-u.uy && u.dy == u.ux-x0) X i = 2; /* straight turn right */ X else X i = -2; /* straight turn left */ X } else if(u.dx && u.dy) { X if((u.dx == u.dy && y0 == u.uy) || X (u.dx != u.dy && y0 != u.uy)) X i = -1; /* half turn left */ X else X i = 1; /* half turn right */ X } else { X if((x0-u.ux == y0-u.uy && !u.dy) || X (x0-u.ux != y0-u.uy && u.dy)) X i = 1; /* half turn right */ X else X i = -1; /* half turn left */ X } X i += u.last_str_turn; X if(i <= 2 && i >= -2) { X u.last_str_turn = i; X u.dx = x0-u.ux, u.dy = y0-u.uy; X } X } X} X X/* something like lookaround, but we are not running */ X/* react only to monsters that might hit us */ Xmonster_nearby() { Xregister int x,y; Xregister struct monst *mtmp; X if(!Blind) X for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){ X if(x == u.ux && y == u.uy) continue; X if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame && X !mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) && X !mtmp->mfroz && !mtmp->msleep && /* aplvax!jcn */ X (!mtmp->minvis || See_invisible)) X return(1); X } X return(0); X} X X#ifdef QUEST Xcansee(x,y) xchar x,y; { Xregister int dx,dy,adx,ady,sdx,sdy,dmax,d; X if(Blind) return(0); X if(!isok(x,y)) return(0); X d = dist(x,y); X if(d < 3) return(1); X if(d > u.uhorizon*u.uhorizon) return(0); X if(!levl[x][y].lit) X return(0); X dx = x - u.ux; adx = abs(dx); sdx = sgn(dx); X dy = y - u.uy; ady = abs(dy); sdy = sgn(dy); X if(dx == 0 || dy == 0 || adx == ady){ X dmax = (dx == 0) ? ady : adx; X for(d = 1; d <= dmax; d++) X if(!rroom(sdx*d,sdy*d)) X return(0); X return(1); X } else if(ady > adx){ X for(d = 1; d <= ady; d++){ X if(!rroom(sdx*( (d*adx)/ady ), sdy*d) || X !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d)) X return(0); X } X return(1); X } else { X for(d = 1; d <= adx; d++){ X if(!rroom(sdx*d, sdy*( (d*ady)/adx )) || X !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 ))) X return(0); X } X return(1); X } X} X Xrroom(x,y) register int x,y; { X return(IS_ROOM(levl[u.ux+x][u.uy+y].typ)); X} X X#else X Xcansee(x,y) xchar x,y; { X if(Blind || u.uswallow) return(0); X if(dist(x,y) < 3) return(1); X if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y && X y <= seehy) return(1); X return(0); X} X#endif /* QUEST /**/ X Xsgn(a) register int a; { X return((a > 0) ? 1 : (a == 0) ? 0 : -1); X} X X#ifdef QUEST Xsetsee() X{ X register x,y; X X if(Blind) { X pru(); X return; X } X for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++) X for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) { X if(cansee(x,y)) X prl(x,y); X } X} X X#else X Xsetsee() X{ X register x,y; X X if(Blind) { X pru(); X return; X } X if(!levl[u.ux][u.uy].lit) { X seelx = u.ux-1; X seehx = u.ux+1; X seely = u.uy-1; X seehy = u.uy+1; X } else { X for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--); X for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++); X for(seely = u.uy; levl[u.ux][seely-1].lit; seely--); X for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++); X } X for(y = seely; y <= seehy; y++) X for(x = seelx; x <= seehx; x++) { X prl(x,y); X } X if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */ X else { X if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1); X if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1); X if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y); X if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y); X } X} X#endif /* QUEST /**/ X Xnomul(nval) Xregister nval; X{ X#ifdef DGKMOD X if(multi < nval) return; /* This is a bug fix by ab@unido */ X#else X if(multi < 0) return; X#endif X multi = nval; X flags.mv = flags.run = 0; X} X Xabon() X{ X#ifdef KAA X if (u.usym != '@') return(mons[u.umonnum].mlevel-3); X#endif X if(u.ustr == 3) return(-3); X else if(u.ustr < 6) return(-2); X else if(u.ustr < 8) return(-1); X else if(u.ustr < 17) return(0); X else if(u.ustr < 69) return(1); /* up to 18/50 */ X else if(u.ustr < 118) return(2); X else return(3); X} X Xdbon() X{ X if (u.usym != '@') return(0); X X if(u.ustr < 6) return(-1); X else if(u.ustr < 16) return(0); X else if(u.ustr < 18) return(1); X else if(u.ustr == 18) return(2); /* up to 18 */ X else if(u.ustr < 94) return(3); /* up to 18/75 */ X else if(u.ustr < 109) return(4); /* up to 18/90 */ X else if(u.ustr < 118) return(5); /* up to 18/99 */ X else return(6); X} X Xlosestr(num) /* may kill you; cause may be poison or monster like 'A' */ Xregister num; X{ X u.ustr -= num; X while(u.ustr < 3) { X u.ustr++; X u.uhp -= 6; X u.uhpmax -= 6; X } X flags.botl = 1; X} X Xlosehp(n,knam) Xregister n; Xregister char *knam; X{ X#ifdef KAA X if (u.mtimedone) { X u.mh -= n; X if (u.mhmax < u.mh) u.mhmax = u.mh; X flags.botl = 1; X if (u.mh < 1) rehumanize(); X return(0); X } X#endif X u.uhp -= n; X if(u.uhp > u.uhpmax) X u.uhpmax = u.uhp; /* perhaps n was negative */ X flags.botl = 1; X if(u.uhp < 1) { X killer = knam; /* the thing that killed you */ X pline("you died"); X done("died"); X } X} X Xlosehp_m(n,mtmp) Xregister n; Xregister struct monst *mtmp; X{ X#ifdef KAA X if (u.mtimedone) { X u.mh -= n; X flags.botl = 1; X if (u.mh < 1) rehumanize(); X return; X } X#endif X u.uhp -= n; X flags.botl = 1; X if(u.uhp < 1) X done_in_by(mtmp); X} X Xlosexp() /* hit by V or W */ X{ X register num; X extern long newuexp(); X X if (u.usym == 'V' || u.usym=='W') return; X X if(u.ulevel > 1) X pline("Goodbye level %u.", u.ulevel--); X else X u.uhp = -1; X num = rnd(10); X u.uhp -= num; X u.uhpmax -= num; X#ifdef SPELLS X num = rnd(u.ulevel/2+1) + 1; /* M. Stephenson */ X u.uen -= num; X if (u.uen < 0) u.uen = 0; X u.uenmax -= num; X if (u.uenmax < 0) u.uenmax = 0; X#endif X u.uexp = newuexp(); X flags.botl = 1; X} X Xinv_weight(){ Xregister struct obj *otmp = invent; Xregister int wt = (u.ugold + 500)/1000; Xregister int carrcap; X#ifdef KAA X if (u.mtimedone) { X if (u.usym == '9') carrcap = MAX_CARR_CAP * 4; X else if (u.usym == 'N') carrcap = MAX_CARR_CAP; X else if (mons[u.umonnum].mlevel <= 3) X carrcap = 5*mons[u.umonnum].mlevel + 30; X else carrcap = 5*mons[u.umonnum].mlevel + 100; X } X#endif X if(Levitation) /* pugh@cornell */ X carrcap = MAX_CARR_CAP; X else { X carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel); X if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; X if(Wounded_legs & LEFT_SIDE) carrcap -= 10; X if(Wounded_legs & RIGHT_SIDE) carrcap -= 10; X } X while(otmp){ X wt += otmp->owt; X otmp = otmp->nobj; X } X return(wt - carrcap); X} X Xinv_cnt(){ Xregister struct obj *otmp = invent; Xregister int ct = 0; X while(otmp){ X ct++; X otmp = otmp->nobj; X } X return(ct); X} X Xlong Xnewuexp() X{ X return(10*(1L << (u.ulevel-1))); X} END_OF_hack.c if test 24139 -ne `wc -c <hack.c`; then echo shar: \"hack.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f wield.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"wield.c\" else echo shar: Extracting \"wield.c\" \(3307 characters\) sed "s/^X//" >wield.c <<'END_OF_wield.c' X/* SCCS Id: @(#)wield.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* wield.c - version 1.0.3 */ X X#include "hack.h" Xextern struct obj zeroobj; Xextern char *hcolor(); X#ifdef KAA Xextern boolean unweapon; X#endif X Xsetuwep(obj) register struct obj *obj; { X setworn(obj, W_WEP); X} X Xdowield() X{ X register struct obj *wep; X register int res = 0; X X multi = 0; X#ifdef KAA X if (cantwield(u.usym)) { X pline("Don't be ridiculous!"); X return(0); X } X#endif X if(!(wep = getobj("#-)", "wield"))) /* nothing */; X else if(uwep == wep) X pline("You are already wielding that!"); X else if(welded(uwep)) X pline("The %s welded to your hand!", X aobjnam(uwep, "are")); X else if(wep == &zeroobj) { X if(uwep == 0){ X pline("You are already empty handed."); X } else { X setuwep((struct obj *) 0); X res++; X pline("You are empty handed."); X } X /* Prevent wielding a cockatrice in pack when not wearing gloves KAA*/ X } else if (!uarmg && wep->otyp == DEAD_COCKATRICE) { X pline("You wield the dead cockatrice in your bare hands."); X pline("You turn to stone ..."); X killer="dead cockatrice"; X done("died"); X } else if(uarms && wep->otyp == TWO_HANDED_SWORD) X pline("You cannot wield a two-handed sword and wear a shield."); X else if(wep->owornmask & (W_ARMOR | W_RING)) X pline("You cannot wield that!"); X else { X setuwep(wep); X res++; X if(welded(uwep)) X pline("The %s %s to your hand!", X aobjnam(uwep, "weld"), X (uwep->quan == 1) ? "itself" : "themselves"); /* a3 */ X else prinv(uwep); X } X#ifdef KAA X if(res && uwep) X unweapon = (uwep->otyp >= BOW || uwep->otyp <= BOOMERANG) ? X TRUE : FALSE; X#endif X return(res); X} X Xcorrode_weapon(){ X if(!uwep || uwep->olet != WEAPON_SYM) return; /* %% */ X if(uwep->rustfree) X pline("Your %s not affected.", aobjnam(uwep, "are")); X else { X pline("Your %s!", aobjnam(uwep, "corrode")); X uwep->spe--; X } X} X Xchwepon(otmp,amount) Xregister struct obj *otmp; Xregister amount; X{ Xregister char *color = (amount < 0) ? "black" : "green"; Xregister char *time; X X if(Hallucination) color=hcolor(); X if(!uwep || uwep->olet != WEAPON_SYM) { X strange_feeling(otmp, X (amount > 0) ? "Your hands twitch." X : "Your hands itch."); X return(0); X } X X if(uwep->otyp == WORM_TOOTH && amount > 0) { X uwep->otyp = CRYSKNIFE; X pline("Your weapon seems sharper now."); X uwep->cursed = 0; X return(1); X } X X if(uwep->otyp == CRYSKNIFE && amount < 0) { X uwep->otyp = WORM_TOOTH; X pline("Your weapon looks duller now."); X return(1); X } X X /* there is a (soft) upper limit to uwep->spe */ X if(amount > 0 && uwep->spe > 5 && rn2(3)) { X pline("Your %s violently %s for a while and then evaporate%s.", X aobjnam(uwep,"glow"),Hallucination ? hcolor() : "green", X plur(uwep->quan)); X X while(uwep) /* let all of them disappear */ X /* note: uwep->quan = 1 is nogood if unpaid */ X useup(uwep); X return(1); X } X if(!rn2(6)) amount *= 2; X time = (amount*amount == 1) ? "moment" : "while"; X pline("Your %s %s for a %s.", X aobjnam(uwep, "glow"), color, time); X uwep->spe += amount; X if(amount > 0) uwep->cursed = 0; X return(1); X} X Xint Xwelded(obj) register struct obj *obj; { X return(obj == uwep && obj->cursed && X (obj->olet == WEAPON_SYM || obj->otyp == HEAVY_IRON_BALL || X obj->otyp == CAN_OPENER || obj->otyp == PICK_AXE)); X} END_OF_wield.c if test 3307 -ne `wc -c <wield.c`; then echo shar: \"wield.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f zap.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"zap.c\" else echo shar: Extracting \"zap.c\" \(23766 characters\) sed "s/^X//" >zap.c <<'END_OF_zap.c' X/* SCCS Id: @(#)zap.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* zap.c - version 1.0.3 */ X X#include "hack.h" X Xextern struct obj *mkobj_at(); Xextern struct monst *makemon(), *mkmon_at(), youmonst; Xstruct monst *bhit(); Xchar *exclam(); X#ifdef KAA Xextern char *xname(); X#endif X Xchar *fl[]= { X "magic missile", X "bolt of fire", X "sleep ray", X "bolt of cold", X "death ray", X "magic missle", /* Spell equivalents of above wands */ X "fireball", X "sleep ray", X "cone of cold", X "finger of death" X}; X X/* Routines for IMMEDIATE wands and spells. */ X/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */ Xbhitm(mtmp, otmp) Xregister struct monst *mtmp; Xregister struct obj *otmp; X{ X wakeup(mtmp); X switch(otmp->otyp) { X case WAN_STRIKING: X#ifdef SPELLS X case SPE_FORCE_BOLT: X#endif X if(u.uswallow || rnd(20) < 10+mtmp->data->ac) { X register int tmp = d(2,12); X hit((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp, exclam(tmp)); X resist(mtmp, otmp->olet, tmp, TELL); X } else miss((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp); X break; X case WAN_SLOW_MONSTER: X#ifdef SPELLS X case SPE_SLOW_MONSTER: X#endif X if(! resist(mtmp, otmp->olet, 0, NOTELL)) X mtmp->mspeed = MSLOW; X break; X case WAN_SPEED_MONSTER: X if (!resist(mtmp, otmp->olet, 0, NOTELL)) X mtmp->mspeed = MFAST; X break; X case WAN_UNDEAD_TURNING: X#ifdef SPELLS X case SPE_TURN_UNDEAD: X#endif X if(index(UNDEAD,mtmp->data->mlet)) { X X if(!resist(mtmp, otmp->olet, rnd(8), NOTELL)) X mtmp->mflee = 1; X } X break; X case WAN_POLYMORPH: X#ifdef SPELLS X case SPE_POLYMORPH: X#endif X if(!resist(mtmp, otmp->olet, 0, NOTELL)) X if( newcham(mtmp,&mons[rn2(CMNUM)]) ) X if (!Hallucination) X objects[otmp->otyp].oc_name_known = 1; X break; X case WAN_CANCELLATION: X#ifdef SPELLS X case SPE_CANCELLATION: X#endif X if(!resist(mtmp, otmp->olet, 0, NOTELL)) X mtmp->mcan = 1; X break; X case WAN_TELEPORTATION: X#ifdef SPELLS X case SPE_TELEPORT_AWAY: X#endif X rloc(mtmp); X break; X case WAN_MAKE_INVISIBLE: X mtmp->minvis = 1; X break; X case WAN_NOTHING: X break; X case WAN_PROBING: X#ifdef PROBING X mstatusline(mtmp); X#else X pline("Nothing Happens."); X#endif X break; X default: X impossible("What an interesting effect (%u)", otmp->otyp); X } X} X Xbhito(obj, otmp) /* object obj was hit by the effect of wand otmp */ Xregister struct obj *obj, *otmp; /* returns TRUE if sth was done */ X{ X register int res = TRUE; X#ifdef DGKMOD X struct obj *otmp2; X#endif X X if(obj == uball || obj == uchain) X res = FALSE; X else X switch(otmp->otyp) { X case WAN_POLYMORPH: X#ifdef SPELLS X case SPE_POLYMORPH: X#endif X /* preserve symbol and quantity, but turn rocks into gems */ X#ifdef DGKMOD X otmp2 = mkobj_at((obj->otyp == ROCK X || obj->otyp == ENORMOUS_ROCK) ? GEM_SYM : obj->olet, X obj->ox, obj->oy); X otmp2->quan = obj->quan; X /* keep special fields (including charges on wands) */ X /* The DGK modification doesn't allow polymorphing a weapon X with enchantments into another one, and doesn't allow X polymorphed rings to have plusses. KAA*/ X if (index("/)[", otmp2->olet)) otmp2->spe = obj->spe; X otmp2->cursed = otmp->cursed; X /* update the weight */ X otmp2->owt = weight(otmp2); X#else X mkobj_at((obj->otyp == ROCK || obj->otyp == ENORMOUS_ROCK) X ? GEM_SYM : obj->olet, X obj->ox, obj->oy) -> quan = obj->quan; X#endif X delobj(obj); X break; X case WAN_STRIKING: X#ifdef SPELLS X case SPE_FORCE_BOLT: X#endif X if(obj->otyp == ENORMOUS_ROCK) X fracture_rock(obj); X else X res = FALSE; X break; X case WAN_CANCELLATION: X#ifdef SPELLS X case SPE_CANCELLATION: X#endif X if(obj->spe && obj->olet != AMULET_SYM) { X obj->known = 0; X obj->spe = 0; X } X break; X case WAN_TELEPORTATION: X#ifdef SPELLS X case SPE_TELEPORT_AWAY: X#endif X rloco(obj); X break; X case WAN_MAKE_INVISIBLE: X obj->oinvis = 1; X break; X case WAN_UNDEAD_TURNING: X#ifdef SPELLS X case SPE_TURN_UNDEAD: X#endif X res = revive(obj); X break; X case WAN_SLOW_MONSTER: /* no effect on objects */ X#ifdef SPELLS X case SPE_SLOW_MONSTER: X#endif X case WAN_SPEED_MONSTER: X case WAN_NOTHING: X case WAN_PROBING: X res = FALSE; X break; X default: X impossible("What an interesting effect (%u)", otmp->otyp); X } X return(res); X} X X/* X * zappable - returns 1 if zap is available, 0 otherwise. X * it removes a charge from the wand if zappable. X * added by GAN 11/03/86 X */ Xint Xzappable(wand) Xregister struct obj *wand; X{ X if(wand->spe < 0 || (wand->spe ==0 && rn2(121))) X return(0); X else { X if(wand->spe == 0) X pline("You wrest one more spell from the worn-out wand."); X wand->spe--; X return(1); X } X} X X/* X * zapnodir - zaps an NODIR wand. X * added by GAN 11/03/86 X */ Xzapnodir(wand) Xregister struct obj *wand; X{ X switch(wand->otyp){ X case WAN_LIGHT: X litroom(TRUE); X break; X case WAN_SECRET_DOOR_DETECTION: X if(!findit()) return(1); X break; X case WAN_CREATE_MONSTER: X { register int cnt = 1; X if(!rn2(23)) cnt += rn2(7) + 1; X while(cnt--) X (void) makemon((struct permonst *) 0, u.ux, u.uy); X } X break; X case WAN_WISHING: X X if(u.uluck + rn2(5) < 0) { X pline("Unfortunately, nothing happens."); X break; X } X makewish(); X break; X } X if(!objects[wand->otyp].oc_name_known) { X objects[wand->otyp].oc_name_known = 1; X more_experienced(0,10); X } X} X Xdozap() X{ X register struct obj *obj; X int damage; X X obj = getobj("/", "zap"); X if(!obj) return(0); X X /* zappable addition done by GAN 11/03/86 */ X if(!zappable(obj)) { X pline("Nothing Happens."); X return(1); X } X if(!(objects[obj->otyp].bits & NODIR) && !getdir(1)) { X pline("The %s glows and fades.",xname(obj)); X return(1); /* make him pay for knowing !NODIR */ X } X#ifdef KAA X if(!u.dx && !u.dy && !u.dz && !(objects[obj->otyp].bits & NODIR)) { X X if((damage = zapyourself(obj))) X losehp(damage,"self-inflicted injury"); X return(1); X } X#endif X weffects(obj); X return(1); X} X X#ifdef KAA X#define makeknown(x) objects[x].oc_name_known = 1 X Xzapyourself(obj) X register struct obj *obj; X{ Xstruct obj *otmp; Xint damage = 0; X X switch(obj->otyp) { X case WAN_STRIKING: X damage=d(8,6); X pline("The wand hits you!"); X break; X case WAN_FIRE: X if (!Fire_resistance) damage=d(12,6); X pline("The wand sprays you with flames!"); X makeknown(WAN_FIRE); X burn_scrolls(); X boil_potions(); X break; X case WAN_COLD: X if (!Cold_resistance) damage=d(12,6); X pline("You are blasted with liquid nitrogen!"); X makeknown(WAN_COLD); X break; X case WAN_MAGIC_MISSILE: X damage = d(4,6); X pline("You are shot at point blank range!"); X makeknown(WAN_MAGIC_MISSILE); X break; X case WAN_POLYMORPH: X makeknown(WAN_POLYMORPH); X polyself(); X break; X case WAN_CANCELLATION: X for(otmp = invent; otmp; otmp = otmp->nobj) X if(otmp != uball && otmp->otyp != AMULET_OF_YENDOR) X otmp->spe = 0; X if(u.mtimedone) rehumanize(); X flags.botl = 1; /* because of potential AC change */ X find_ac(); X break; X case WAN_MAKE_INVISIBLE: X HInvis |= INTRINSIC; X /* Tough luck if you cannot see invisible! */ X if (!See_invisible) newsym(u.ux, u.uy); X break; X case WAN_SPEED_MONSTER: X Fast |= INTRINSIC; X break; X case WAN_SLEEP: X makeknown(WAN_SLEEP); X pline("The sleep ray hits you!"); X nomul(-rn2(50)); X break; X case WAN_SLOW_MONSTER: X Fast = 0; X break; X case WAN_TELEPORTATION: X tele(); X break; X case WAN_DEATH: X pline("You irradiate yourself with pure energy!"); X pline("You die."); X killer = "wand of death"; X done("died"); X break; X case WAN_DIGGING: X case WAN_UNDEAD_TURNING: X case WAN_NOTHING: X break; X default: impossible("object %d zap?",obj->otyp); X } X return(damage); X} X#endif /* KAA /**/ X X/* called for various wand and spell effects - M. Stephenson */ Xweffects(obj) X register struct obj *obj; X{ X xchar zx,zy; X X if(objects[obj->otyp].bits & IMMEDIATE) { X if(u.uswallow) X bhitm(u.ustuck, obj); X else if(u.dz) { X if(u.dz > 0 && o_at(u.ux,u.uy)) { X register struct obj *otmp; X X /* changed by GAN to hit all objects there */ X for(otmp = fobj; otmp ; otmp = otmp->nobj) X if(otmp->ox == u.ux && X otmp->oy == u.uy) X (void) bhito(otmp, obj); X } X } else X (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj); X } else { X switch(obj->otyp){ X case WAN_LIGHT: X#ifdef SPELLS X case SPE_LIGHT: X#endif X litroom(TRUE); X break; X case WAN_SECRET_DOOR_DETECTION: X#ifdef SPELLS X case SPE_DETECT_UNSEEN: X#endif X if(!findit()) return(1); X break; X case WAN_CREATE_MONSTER: X { register int cnt = 1; X if(!rn2(23)) cnt += rn2(7) + 1; X while(cnt--) X (void) makemon((struct permonst *) 0, u.ux, u.uy); X } X break; X case WAN_WISHING: X if(u.uluck + rn2(5) < 0) { X pline("Unfortunately, nothing happens."); X break; X } X makewish(); X break; X case WAN_DIGGING: X#ifdef SPELLS X case SPE_DIG: X#endif X /* Original effect (approximately): X * from CORR: dig until we pierce a wall X * from ROOM: piece wall and dig until we reach X * an ACCESSIBLE place. X * Currently: dig for digdepth positions; X * also down on request of Lennart Augustsson. X */ X { register struct rm *room; X register int digdepth; X if(u.uswallow) { X register struct monst *mtmp = u.ustuck; X X pline("You pierce %s's stomach wall!", X monnam(mtmp)); X mtmp->mhp = 1; /* almost dead */ X unstuck(mtmp); X mnexto(mtmp); X break; X } X if(u.dz) { X if(u.dz < 0) { X pline("You loosen a rock from the ceiling."); X pline("It falls on your head!"); X losehp(1, "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 dighole(); X } X break; X } X zx = u.ux+u.dx; X zy = u.uy+u.dy; X digdepth = 8 + rn2(18); X Tmp_at(-1, '*'); /* open call */ X while(--digdepth >= 0) { X if(!isok(zx,zy)) break; X room = &levl[zx][zy]; X Tmp_at(zx,zy); X if(!xdnstair){ X if(zx < 3 || zx > COLNO-3 || X zy < 3 || zy > ROWNO-3) X break; X if(room->typ == HWALL || X room->typ == VWALL){ X room->typ = ROOM; X break; X } X } else X if(room->typ == HWALL || room->typ == VWALL || X room->typ == SDOOR || room->typ == LDOOR){ X room->typ = DOOR; X digdepth -= 2; X } else X if(room->typ == SCORR || !room->typ) { X room->typ = CORR; X digdepth--; X } X mnewsym(zx,zy); X zx += u.dx; X zy += u.dy; X } X mnewsym(zx,zy); /* not always necessary */ X Tmp_at(-1,-1); /* closing call */ X break; X } X default: X#ifdef SPELLS X if((int) obj->otyp >= SPE_MAGIC_MISSILE) { X X buzz((int) obj->otyp - SPE_MAGIC_MISSILE + 5, X u.ux, u.uy, u.dx, u.dy); X } else X#endif X X buzz((int) obj->otyp - WAN_MAGIC_MISSILE, X u.ux, u.uy, u.dx, u.dy); X break; X } X if(!objects[obj->otyp].oc_name_known) { X objects[obj->otyp].oc_name_known = 1; X more_experienced(0,10); X } X } X return; X} X Xchar * Xexclam(force) Xregister int force; X{ X /* force == 0 occurs e.g. with sleep ray */ X /* note that large force is usual with wands so that !! would X require information about hand/weapon/wand */ X return( (force < 0) ? "?" : (force <= 4) ? "." : "!" ); X} X Xhit(str,mtmp,force) Xregister char *str; Xregister struct monst *mtmp; Xregister char *force; /* usually either "." or "!" */ X{ X if(!cansee(mtmp->mx,mtmp->my)) pline("The %s hits it.", str); X else pline("The %s hits %s%s", str, monnam(mtmp), force); X} X Xmiss(str,mtmp) Xregister char *str; Xregister struct monst *mtmp; X{ X if(!cansee(mtmp->mx,mtmp->my)) pline("The %s misses it.",str); X else pline("The %s misses %s.",str,monnam(mtmp)); X} X X/* bhit: called when a weapon is thrown (sym = obj->olet) or when an X IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of X range or when a monster is hit; the monster is returned, and bhitpos X is set to the final position of the weapon thrown; the ray of a wand X may affect several objects and monsters on its path - for each of X these an argument function is called. */ X/* check !u.uswallow before calling bhit() */ X Xstruct monst * Xbhit(ddx,ddy,range,sym,fhitm,fhito,obj) Xregister int ddx,ddy,range; /* direction and range */ Xchar sym; /* symbol displayed on path */ Xint (*fhitm)(), (*fhito)(); /* fns called when mon/obj hit */ Xstruct obj *obj; /* 2nd arg to fhitm/fhito */ X{ X register struct monst *mtmp; X register struct obj *otmp; X register int typ; X X bhitpos.x = u.ux; X bhitpos.y = u.uy; X X if(sym) tmp_at(-1, sym); /* open call */ X while(range-- > 0) { X bhitpos.x += ddx; X bhitpos.y += ddy; X typ = levl[bhitpos.x][bhitpos.y].typ; X if(mtmp = m_at(bhitpos.x,bhitpos.y)){ X if(sym) { X tmp_at(-1, -1); /* close call */ X return(mtmp); X } X (*fhitm)(mtmp, obj); X range -= 3; X } X /* modified by GAN to hit all objects */ X if(fhito && o_at(bhitpos.x,bhitpos.y)){ X int hitanything = 0; X for(otmp = fobj; otmp; otmp = otmp->nobj) X if(otmp->ox == bhitpos.x && X otmp->oy == bhitpos.y) X hitanything += (*fhito)(otmp, obj); X if(hitanything) range--; X } X if(!ZAP_POS(typ)) { X bhitpos.x -= ddx; X bhitpos.y -= ddy; X break; X } X if(sym) tmp_at(bhitpos.x, bhitpos.y); X } X X /* leave last symbol unless in a pool */ X if(sym) X tmp_at(-1, (levl[bhitpos.x][bhitpos.y].typ == POOL) ? -1 : 0); X return(0); X} X Xstruct monst * Xboomhit(dx,dy) { X register int i, ct; X register struct monst *mtmp; X char sym = ')'; X extern schar xdir[], ydir[]; X X bhitpos.x = u.ux; X bhitpos.y = u.uy; X X for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break; X tmp_at(-1, sym); /* open call */ X for(ct=0; ct<10; ct++) { X if(i == 8) i = 0; X sym = ')' + '(' - sym; X tmp_at(-2, sym); /* change let call */ X dx = xdir[i]; X dy = ydir[i]; X bhitpos.x += dx; X bhitpos.y += dy; X if(mtmp = m_at(bhitpos.x, bhitpos.y)){ X tmp_at(-1,-1); X return(mtmp); X } X if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) { X bhitpos.x -= dx; X bhitpos.y -= dy; X break; X } X if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */ X if(rn2(20) >= 10+u.ulevel){ /* we hit ourselves */ X (void) thitu(10, rnd(10), "boomerang"); X break; X } else { /* we catch it */ X tmp_at(-1,-1); X pline("Skillfully, you catch the boomerang."); X return(&youmonst); X } X } X tmp_at(bhitpos.x, bhitpos.y); X if(ct % 5 != 0) i++; X } X tmp_at(-1, -1); /* do not leave last symbol */ X return(0); X} X Xchar Xdirlet(dx,dy) register dx,dy; { X return X (dx == dy) ? '\\' : (dx && dy) ? '/' : dx ? '-' : '|'; X} X X/* type == -1: monster spitting fire at you */ X/* type == -1,-2,-3: bolts sent out by wizard */ X/* called with dx = dy = 0 with vertical bolts */ Xbuzz(type,sx,sy,dx,dy) Xregister int type; Xregister xchar sx,sy; Xregister int dx,dy; X{ X int abstype = (type == 10) ? 1 : abs(type); X register char *fltxt = (type == -1 || type == 10) ? "blaze of fire" : fl[abstype]; X struct rm *lev; X xchar range; X struct monst *mon; X X if(u.uswallow) { X register int tmp; X X if(type < 0) return; X tmp = zhit(u.ustuck, type); X pline("The %s rips into %s%s", X fltxt, monnam(u.ustuck), exclam(tmp)); X return; X } X if(type < 0) pru(); X range = rn1(7,7); X Tmp_at(-1, dirlet(dx,dy)); /* open call */ X while(range-- > 0) { X sx += dx; X sy += dy; X if((lev = &levl[sx][sy])->typ) Tmp_at(sx,sy); X else { X int bounce = 0; X if(cansee(sx-dx,sy-dy)) X pline("The %s bounces!", fltxt); X if(ZAP_POS(levl[sx][sy-dy].typ)) X bounce = 1; X if(ZAP_POS(levl[sx-dx][sy].typ)) { X if(!bounce || rn2(2)) bounce = 2; X } X switch(bounce){ X case 0: X dx = -dx; X dy = -dy; X continue; X case 1: X dy = -dy; X sx -= dx; X break; X case 2: X dx = -dx; X sy -= dy; X break; X } X Tmp_at(-2,dirlet(dx,dy)); X continue; X } X if(lev->typ == POOL && abstype == 1 /* fire */) { X range -= 3; X lev->typ = ROOM; X if(cansee(sx,sy)) { X mnewsym(sx,sy); X pline("The water evaporates."); X } else X pline("You hear a hissing sound."); X } X if(o_at(sx,sy) && abstype == 1) X if(burn_floor_scrolls(sx,sy) && cansee(sx,sy)) { X mnewsym(sx,sy); X pline("You see a puff of smoke."); X } X if((mon = m_at(sx,sy)) && X (type != -1 || mon->data->mlet != 'D')) { X wakeup(mon); X if(rnd(20) < 18 + mon->data->ac) { X register int tmp = zhit(mon,abstype); X if(mon->mhp < 1) { X if(type < 0) { X if(cansee(mon->mx,mon->my)) X pline("%s is killed by the %s!", X Monnam(mon), fltxt); X mondied(mon); X } else X killed(mon); X } else X hit(fltxt, mon, exclam(tmp)); X range -= 2; X } else X miss(fltxt,mon); X } else if(sx == u.ux && sy == u.uy) { X nomul(0); X if(rnd(20) < 18+u.uac) { X register int dam = 0; X range -= 2; X pline("The %s hits you!",fltxt); X switch(abstype) { X case 0: X case 5: dam = d(2,6); X break; X case 1: X case 6: if(Fire_resistance) X pline("You don't feel hot!"); X else dam = d(6,6); X if(!rn2(3)) { X boil_potions(); X burn_scrolls(); X } X break; X case 2: X case 7: nomul(-rnd(25)); /* sleep ray */ X break; X case 3: X case 8: if(Cold_resistance) X pline("You don't feel cold!"); X else dam = d(6,6); X break; X case 4: X case 9: u.uhp = -1; X break; X } X losehp(dam,fltxt); X } else pline("The %s whizzes by you!",fltxt); X stop_occupation(); X } X if(!ZAP_POS(lev->typ)) { X int bounce = 0, rmn; X if(cansee(sx,sy)) pline("The %s bounces!",fltxt); X range--; X if(!dx || !dy || !rn2(20)){ X dx = -dx; X dy = -dy; X } else { X if(ZAP_POS(rmn = levl[sx][sy-dy].typ) && X (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ))) X bounce = 1; X if(ZAP_POS(rmn = levl[sx-dx][sy].typ) && X (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ))) X if(!bounce || rn2(2)) X bounce = 2; X X switch(bounce){ X case 0: X dy = -dy; X dx = -dx; X break; X case 1: X dy = -dy; X break; X case 2: X dx = -dx; X break; X } X Tmp_at(-2, dirlet(dx,dy)); X } X } X } X Tmp_at(-1,-1); X} X Xzhit(mon,type) /* returns damage to mon */ Xregister struct monst *mon; Xregister type; X{ X register int tmp = 0; X X switch(type) { X case 0: /* magic missile */ X case 5: tmp = d(2,6); X break; X case -1: /* Dragon blazing fire */ X case 1: /* fire wand*/ X case 6: /* fire spell */ X case 10: /* Polymorphed human blazing fire */ X if(index("Dg", mon->data->mlet)) break; X tmp = d(6,6); X if(index("YF", mon->data->mlet)) tmp += 7; X break; X case 2: /* sleep*/ X case 7: tmp = 0; X if(!resist(mon, (type == 2) ? '/' : '+', 0, NOTELL)) X mon->mfroz = 1; X break; X case 3: /* cold */ X case 8: X if(index("YFgf", mon->data->mlet)) break; X tmp = d(6,6); X if(mon->data->mlet == 'D') tmp += 7; X break; X case 4: /* death*/ X case 9: X if(index(UNDEAD, mon->data->mlet)) break; X tmp = mon->mhp+1; X break; X } X if (resist(mon, (type < 5) ? '/' : '+', 0, NOTELL)) tmp /= 2; X mon->mhp -= tmp; X return(tmp); X} X X#define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\ X ? 'a' + (otyp - DEAD_ACID_BLOB)\ X : '@' + (otyp - DEAD_HUMAN)) Xrevive(obj) Xregister struct obj *obj; X{ X register struct monst *mtmp; X register int let; X X if(obj->olet == FOOD_SYM && obj->otyp > CORPSE) { X#ifdef KAA X switch (obj->otyp) { X case DEAD_HUMAN: { let = 'Z'; break; } X case DEAD_GIANT: { let = '9'; break; } X case DEAD_DEMON: { let = '&'; break; } X default: let = CORPSE_I_TO_C(obj->otyp); X } X delobj(obj); X/* Originally there was a bug which caused the object not to be erased X from the screen. This happened because first the monster got created, X then the corpse removed. Although delobj() called unpobj(), the object X didn't get erased from the screen because the monster was sitting on top X of it. Solution: place the delobj() call before the mkmon() call. */ X mtmp = mkmon_at(let, obj->ox, obj->oy); X if (mtmp && obj->otyp == DEAD_HUMAN) { X mtmp->mhp = mtmp->mhpmax = 100; X mtmp->mspeed = MFAST; X } X#endif X /* do not (yet) revive shopkeepers */ X /* Note: this might conceivably produce two monsters X at the same position - strange, but harmless */ X#ifndef KAA X delobj(obj); X mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp),obj->ox,obj->oy); X#endif X } X return(!!mtmp); /* TRUE if some monster created */ X} X Xrloco(obj) Xregister struct obj *obj; X{ X register tx,ty,otx,oty; X X otx = obj->ox; X oty = obj->oy; X do { X tx = rn1(COLNO-3,2); X ty = rn2(ROWNO); X } while(!goodpos(tx,ty)); X obj->ox = tx; X obj->oy = ty; X if(cansee(otx,oty)) X newsym(otx,oty); X} X Xfracture_rock(obj) /* fractured by pick-axe or wand of striking */ Xregister struct obj *obj; /* no texts here! */ X{ X /* unpobj(obj); */ X obj->otyp = ROCK; X obj->quan = 7 + rn2(60); X obj->owt = weight(obj); X obj->olet = WEAPON_SYM; X if(cansee(obj->ox,obj->oy)) X prl(obj->ox,obj->oy); X} X Xboil_potions() X{ X register struct obj *obj, *obj2; X register int scrquan, i; X X for(obj = invent; obj; obj = obj2) { X obj2 = obj->nobj; X if(obj->olet == POTION_SYM) { X scrquan = obj->quan; X for(i = 1; i <= scrquan; i++) X if(!rn2(3)) { X pline("%s %s boils and explodes!", X (obj->quan != 1) ? "One of your" : "Your", X xname(obj)); X potionbreathe(obj); X useup(obj); X losehp(rn2(4),"boiling potion"); X } X } X } X} X Xburn_scrolls() X{ X register struct obj *obj, *obj2; X register int cnt = 0; X register int scrquan, i; X X for(obj = invent; obj; obj = obj2) { X obj2 = obj->nobj; X if(obj->olet == SCROLL_SYM) { X scrquan = obj->quan; X for(i = 1; i <= scrquan ; i++) X if(!rn2(3)) { X cnt++; X useup(obj); X } X } X } X X /* "Killed by a burning scrolls" doesn't make too much sense. KAA*/ X if (cnt) { X pline("%s of your scrolls catch%s fire!", X cnt==1 ? "One" : "Some", cnt==1 ? "es" : ""); X if(Fire_resistance) X pline("You aren't hurt!"); X else X losehp(cnt,"burning scroll"); X } X} X Xresist(mtmp, olet, damage, tell) Xregister struct monst *mtmp; Xregister char olet; Xregister int damage, tell; X{ Xregister int resisted = 0; X#ifdef HARD Xregister int level; X X switch(olet) { X X case '/': level = 8; X break; X X case '?': level = 6; X break; X X case '!': level = 5; X break; X X default: level = u.ulevel; X break; X } X X resisted = (rn2(100) - mtmp->data->mlevel + level) < mtmp->data->mr; X if(resisted) { X X if(tell) pline("The %s resists!", mtmp->data->mname); X mtmp->mhp -= damage/2; X } else X#endif X mtmp->mhp -= damage; X X if(mtmp->mhp < 1) killed(mtmp); X return(resisted); X} X X/* X * burn scrolls on floor at position x,y X * return the number of scrolls burned X */ Xint Xburn_floor_scrolls(x,y) X{ X register struct obj *obj, *obj2; X register int scrquan, i; X register int cnt = 0; X X for(obj = fobj; obj; obj = obj2) { X obj2 = obj->nobj; X /* Bug fix - KAA */ X if(obj->ox == x && obj->oy == y && obj->olet == SCROLL_SYM) { X scrquan = obj->quan; X for(i = 1; i <= scrquan ; i++) X if(!rn2(3)) { X cnt++; X useupf(obj); X } X } X } X return(cnt); X} X Xmakewish() /* Separated as there are now 3 places you can wish at. */ X{ X char buf[BUFSZ]; X register struct obj *otmp; X extern struct obj *readobjnam(), *addinv(); X int wishquan, mergquan; X X pline("You may wish for an object. What do you want? "); X getlin(buf); X if(buf[0] == '\033') buf[0] = 0; X otmp = readobjnam(buf); X#ifdef KAA X/* Wishing for gold has been implemented in readobjnam() and returns 0 X if successful. */ X if (otmp) { X#endif X wishquan = otmp->quan; X otmp = addinv(otmp); X /* indented lines added below so quantity shows X * right. GAN - 11/13/86 X */ X mergquan = otmp->quan; X otmp->quan = wishquan; /* to fool prinv() */ X prinv(otmp); X otmp->quan = mergquan; X#ifdef KAA X } X#endif X} END_OF_zap.c if test 23766 -ne `wc -c <zap.c`; then echo shar: \"zap.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 3 \(of 16\). cp /dev/null ark3isdone 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 ,