billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 10, Issue 77 Archive-name: nethack3p9/Part32 Supersedes: NetHack3: Volume 7, Issue 56-93 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 32 (of 56)." # Contents: src/mklev.c src/monmove.c src/rip.c # Wrapped by billr@saab on Wed Jul 11 17:11:39 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/mklev.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/mklev.c'\" else echo shar: Extracting \"'src/mklev.c'\" \(28964 characters\) sed "s/^X//" >'src/mklev.c' <<'END_OF_FILE' X/* SCCS Id: @(#)mklev.c 3.0 89/12/06 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X X/* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */ X/* croom->lx etc are schar (width <= int), so % arith ensures that */ X/* conversion of result to int is reasonable */ X X#ifdef SINKS Xstatic void FDECL(mksink,(struct mkroom *)); X#endif X#ifdef ALTARS Xstatic void FDECL(mkaltar,(struct mkroom *)); X#endif Xstatic boolean FDECL(occupied,(XCHAR_P,XCHAR_P)); Xstatic void NDECL(makevtele); Xstatic void NDECL(init_levels); Xstatic void NDECL(makelevel); Xstatic boolean FDECL(bydoor,(XCHAR_P,XCHAR_P)); Xstatic boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*)); Xstatic void FDECL(makeniche,(int)); Xstatic void NDECL(make_niches); Xstatic void NDECL(makebigroom); Xstatic void FDECL(addrsx,(int,int,int,int,BOOLEAN_P)); Xstatic void FDECL(addrs,(int,int,int,int)); XSTATIC_PTR int FDECL(comp,(genericptr_t,genericptr_t)); Xstatic void FDECL(dosdoor,(int,int,struct mkroom *,int)); Xstatic void NDECL(makecorridors); Xstatic void FDECL(join,(int,int)); Xstatic int NDECL(makerooms); Xstatic int FDECL(maker,(SCHAR_P,SCHAR_P,SCHAR_P,SCHAR_P,BOOLEAN_P)); Xstatic void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P)); X Xint Xsomex(croom) Xregister struct mkroom *croom; X{ X return rn2(croom->hx-croom->lx+1) + croom->lx; X} X Xint Xsomey(croom) Xregister struct mkroom *croom; X{ X return rn2(croom->hy-croom->ly+1) + croom->ly; X} X X#define XLIM 4 /* define minimum required space around a room */ X#define YLIM 3 Xboolean secret; /* TRUE while making a vault: increase [XY]LIM */ Xstruct rm zerorm; Xschar nxcor; Xboolean goldseen; X X/* Definitions used by makerooms() and addrs() */ X#define MAXRS 50 /* max lth of temp rectangle table - arbitrary */ Xstruct rectangle { X xchar rlx,rly,rhx,rhy; X} rs[MAXRS+1]; Xint rscnt,rsmax; /* 0..rscnt-1: currently under consideration */ X /* rscnt..rsmax: discarded */ X Xstatic void Xaddrsx(lx,ly,hx,hy,discarded) Xregister int lx,ly,hx,hy; Xboolean discarded; /* piece of a discarded area */ X{ X register struct rectangle *rsp; X X /* check inclusions */ X for(rsp = rs; rsp < &rs[rsmax]; rsp++) { X if(lx >= rsp->rlx && hx <= rsp->rhx && X ly >= rsp->rly && hy <= rsp->rhy) X return; X } X X /* make a new entry */ X if(rsmax >= MAXRS) { X#ifdef WIZARD X if(wizard) pline("MAXRS may be too small."); X#endif X return; X } X rsmax++; X if(!discarded) { X *rsp = rs[rscnt]; X rsp = &rs[rscnt]; X rscnt++; X } X rsp->rlx = lx; X rsp->rly = ly; X rsp->rhx = hx; X rsp->rhy = hy; X} X Xstatic void Xaddrs(lowx,lowy,hix,hiy) Xregister int lowx,lowy,hix,hiy; X{ X register struct rectangle *rsp; X register int lx,ly,hx,hy,xlim,ylim; X boolean discarded; X X xlim = XLIM + secret; X ylim = YLIM + secret; X X /* walk down since rscnt and rsmax change */ X for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) { X X if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy || X (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy) X continue; X if((discarded = (rsp >= &rs[rscnt]))) { X *rsp = rs[--rsmax]; X } else { X rsmax--; X rscnt--; X *rsp = rs[rscnt]; X if(rscnt != rsmax) X rs[rscnt] = rs[rsmax]; X } X if(lowy - ly > 2*ylim + 4) X addrsx(lx,ly,hx,lowy-2,discarded); X if(lowx - lx > 2*xlim + 4) X addrsx(lx,ly,lowx-2,hy,discarded); X if(hy - hiy > 2*ylim + 4) X addrsx(lx,hiy+2,hx,hy,discarded); X if(hx - hix > 2*xlim + 4) X addrsx(hix+2,ly,hx,hy,discarded); X } X} X X/* Args must be genericptr_t so that qsort will always be happy. */ X XSTATIC_PTR int Xcomp(vx,vy) Xgenericptr_t vx; Xgenericptr_t vy; X{ X#ifdef LINT X/* lint complains about possible pointer alignment problems, but we know X that vx and vy are always properly aligned. Hence, the following X bogus definition: X*/ X return (vx == vy) ? 0 : -1; X#else X register struct mkroom *x, *y; X X x = (struct mkroom *)vx; X y = (struct mkroom *)vy; X if(x->lx < y->lx) return(-1); X return(x->lx > y->lx); X#endif /* LINT */ X} X Xstatic void Xfinddpos(cc, xl,yl,xh,yh) Xcoord *cc; Xxchar xl,yl,xh,yh; X{ X register xchar x, y; X X x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); X y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); X if(okdoor(x, y)) X goto gotit; X X for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) X if(okdoor(x, y)) X goto gotit; X X for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) X if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR) X goto gotit; X /* cannot find something reasonable -- strange */ X x = xl; X y = yh; Xgotit: X cc->x = x; X cc->y = y; X return; X} X X/* Only called from makerooms() and makebigroom() */ Xstatic int Xmaker(lowx,ddx,lowy,ddy,lit) Xschar lowx,ddx,lowy,ddy; Xboolean lit; X{ X register struct mkroom *croom; X register int x, y, hix = lowx+ddx, hiy = lowy+ddy; X register int xlim = XLIM + secret, ylim = YLIM + secret; X X if(nroom >= MAXNROFROOMS) return(0); X if(lowx < XLIM) lowx = XLIM; X if(lowy < YLIM) lowy = YLIM; X if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1; X if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1; Xchk: X if(hix <= lowx || hiy <= lowy) return(0); X X /* check area around room (and make room smaller if necessary) */ X for(x = lowx - xlim; x <= hix + xlim; x++) { X for(y = lowy - ylim; y <= hiy + ylim; y++) { X if(isok(x,y) && levl[x][y].typ) { X#ifdef WIZARD X if(wizard && !secret) X pline("Strange area [%d,%d] in maker().",x,y); X#endif X if(!rn2(3)) return(0); X if(x < lowx) X lowx = x+xlim+1; X else X hix = x-xlim-1; X if(y < lowy) X lowy = y+ylim+1; X else X hiy = y-ylim-1; X goto chk; X } X } X } X X croom = &rooms[nroom]; X X /* on low levels the room is lit (usually) */ X /* secret vaults are always lit */ X /* some other rooms may require lighting */ X if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) { X for(x = lowx-1; x <= hix+1; x++) X for(y = lowy-1; y <= hiy+1; y++) X levl[x][y].lit = 1; X croom->rlit = 1; X } else X croom->rlit = 0; X croom->lx = lowx; X croom->hx = hix; X croom->ly = lowy; X croom->hy = hiy; X croom->rtype = OROOM; X croom->doorct = 0; X /* if we're not making a vault, doorindex will still be 0 X * if we are, we'll have problems adding niches to the previous room X * unless fdoor is at least doorindex X */ X croom->fdoor = doorindex; X X for(x = lowx-1; x <= hix+1; x++) X for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { X levl[x][y].typ = HWALL; X levl[x][y].scrsym = HWALL_SYM; X } X for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) X for(y = lowy; y <= hiy; y++) { X levl[x][y].typ = VWALL; X levl[x][y].scrsym = VWALL_SYM; X } X for(x = lowx; x <= hix; x++) X for(y = lowy; y <= hiy; y++) { X levl[x][y].typ = ROOM; X levl[x][y].scrsym = ROOM_SYM; X } X levl[lowx-1][lowy-1].typ = TLCORNER; X levl[hix+1][lowy-1].typ = TRCORNER; X levl[lowx-1][hiy+1].typ = BLCORNER; X levl[hix+1][hiy+1].typ = BRCORNER; X levl[lowx-1][lowy-1].scrsym = TLCORN_SYM; X levl[hix+1][lowy-1].scrsym = TRCORN_SYM; X levl[lowx-1][hiy+1].scrsym = BLCORN_SYM; X levl[hix+1][hiy+1].scrsym = BRCORN_SYM; X X smeq[nroom] = nroom; X croom++; X croom->hx = -1; X nroom++; X return(1); X} X Xstatic int Xmakerooms() { Xregister struct rectangle *rsp; Xregister int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy; Xint tryct = 0, xlim, ylim; X X /* init */ X xlim = XLIM + secret; X ylim = YLIM + secret; X if(nroom == 0) { X rsp = rs; X rsp->rlx = rsp->rly = 0; X rsp->rhx = COLNO-1; X rsp->rhy = ROWNO-1; X rsmax = 1; X } X rscnt = rsmax; X X /* make rooms until satisfied */ X while(rscnt > 0 && nroom < MAXNROFROOMS-1) { X if(!secret && nroom > (MAXNROFROOMS/4) && X !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom))) X return 0; X X /* pick a rectangle */ X rsp = &rs[rn2(rscnt)]; X hx = rsp->rhx; X hy = rsp->rhy; X lx = rsp->rlx; X ly = rsp->rly; X X /* find size of room */ X if(secret) X dx = dy = 1; X else { X dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8); X dy = 2 + rn2(4); X if(dx*dy > 50) X dy = 50/dx; X } X X /* look whether our room will fit */ X if(hx-lx < dx + (dx>>1) + 2*xlim || X hy-ly < dy + dy/3 + 2*ylim) { X /* no, too small */ X /* maybe we throw this area out */ X if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) { X rscnt--; X rs[rsmax] = *rsp; X *rsp = rs[rscnt]; X rs[rscnt] = rs[rsmax]; X tryct = 0; X } else X tryct++; X continue; X } X X lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1); X lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1); X hix = lowx + dx; X hiy = lowy + dy; X X if(maker(lowx, dx, lowy, dy, FALSE)) { X if(secret) return(1); X addrs(lowx-1, lowy-1, hix+1, hiy+1); X tryct = 0; X } else X if(tryct++ > 100) X break; X } X return(0); /* failed to make vault - very strange */ X} X Xstatic void Xjoin(a,b) Xregister int a, b; X{ X coord cc,tt; X register int tx, ty, xx, yy; X register struct rm *crm; X register struct mkroom *croom, *troom; X register int dx, dy, dix, diy, cct; X X croom = &rooms[a]; X troom = &rooms[b]; X X /* find positions cc and tt for doors in croom and troom X and direction for a corridor between them */ X X if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; X if(troom->lx > croom->hx) { X dx = 1; X dy = 0; X xx = croom->hx+1; X tx = troom->lx-1; X finddpos(&cc, xx, croom->ly, xx, croom->hy); X finddpos(&tt, tx, troom->ly, tx, troom->hy); X } else if(troom->hy < croom->ly) { X dy = -1; X dx = 0; X yy = croom->ly-1; X finddpos(&cc, croom->lx, yy, croom->hx, yy); X ty = troom->hy+1; X finddpos(&tt, troom->lx, ty, troom->hx, ty); X } else if(troom->hx < croom->lx) { X dx = -1; X dy = 0; X xx = croom->lx-1; X tx = troom->hx+1; X finddpos(&cc, xx, croom->ly, xx, croom->hy); X finddpos(&tt, tx, troom->ly, tx, troom->hy); X } else { X dy = 1; X dx = 0; X yy = croom->hy+1; X ty = troom->ly-1; X finddpos(&cc, croom->lx, yy, croom->hx, yy); X finddpos(&tt, troom->lx, ty, troom->hx, ty); X } X xx = cc.x; X yy = cc.y; X tx = tt.x - dx; X ty = tt.y - dy; X if(nxcor && levl[xx+dx][yy+dy].typ) X return; X dodoor(xx,yy,croom); X X cct = 0; X while(xx != tx || yy != ty) { X xx += dx; X yy += dy; X X /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ X if(cct++ > 500 || (nxcor && !rn2(35))) X return; X X if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) X return; /* impossible */ X X crm = &levl[xx][yy]; X if(!(crm->typ)) { X if(rn2(100)) { X crm->typ = CORR; X crm->scrsym = CORR_SYM; X if(nxcor && !rn2(50)) X (void) mksobj_at(BOULDER, xx, yy); X } else { X crm->typ = SCORR; X crm->scrsym = ' '; /* _not_ STONE_SYM */ X } X } else X if(crm->typ != CORR && crm->typ != SCORR) { X /* strange ... */ X return; X } X X /* find next corridor position */ X dix = abs(xx-tx); X diy = abs(yy-ty); X X /* do we have to change direction ? */ X if(dy && dix > diy) { X register int ddx = (xx > tx) ? -1 : 1; X X crm = &levl[xx+ddx][yy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { X dx = ddx; X dy = 0; X continue; X } X } else if(dx && diy > dix) { X register int ddy = (yy > ty) ? -1 : 1; X X crm = &levl[xx][yy+ddy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { X dy = ddy; X dx = 0; X continue; X } X } X X /* continue straight on? */ X crm = &levl[xx+dx][yy+dy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) X continue; X X /* no, what must we do now?? */ X if(dx) { X dx = 0; X dy = (ty < yy) ? -1 : 1; X crm = &levl[xx+dx][yy+dy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) X continue; X dy = -dy; X continue; X } else { X dy = 0; X dx = (tx < xx) ? -1 : 1; X crm = &levl[xx+dx][yy+dy]; X if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) X continue; X dx = -dx; X continue; X } X } X X /* we succeeded in digging the corridor */ X dodoor(tt.x, tt.y, troom); X X if(smeq[a] < smeq[b]) X smeq[b] = smeq[a]; X else X smeq[a] = smeq[b]; X} X Xstatic void Xmakecorridors() { X register int a, b; X X nxcor = 0; X for(a = 0; a < nroom-1; a++) X join(a, a+1); X for(a = 0; a < nroom-2; a++) X if(smeq[a] != smeq[a+2]) X join(a, a+2); X for(a = 0; a < nroom; a++) X for(b = 0; b < nroom; b++) X if(smeq[a] != smeq[b]) X join(a, b); X if(nroom > 2) X for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) { X a = rn2(nroom); X b = rn2(nroom-2); X if(b >= a) b += 2; X join(a, b); X } X} X Xstatic void Xdosdoor(x,y,aroom,type) Xregister int x, y; Xregister struct mkroom *aroom; Xregister int type; X{ X register struct mkroom *broom; X register int tmp; X boolean shdoor = in_shop(x, y); X X if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */ X type = DOOR; X levl[x][y].typ = type; X if(type == DOOR) { X if(!rn2(3)) { /* is it a locked door, closed, or a doorway? */ X if(!rn2(5)) X levl[x][y].doormask = D_ISOPEN; X else if(!rn2(6)) X levl[x][y].doormask = D_LOCKED; X else X levl[x][y].doormask = D_CLOSED; X X if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25)) X levl[x][y].doormask |= D_TRAPPED; X } else X#ifdef STUPID X if (shdoor) X levl[x][y].doormask = D_ISOPEN; X else X levl[x][y].doormask = D_NODOOR; X#else X levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR); X#endif X levl[x][y].scrsym = news0(x,y); X } else { /* SDOOR */ X if(shdoor || !rn2(5)) levl[x][y].doormask = D_LOCKED; X else levl[x][y].doormask = D_CLOSED; X X if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED; X } X aroom->doorct++; X broom = aroom+1; X if(broom->hx < 0) tmp = doorindex; else X for(tmp = doorindex; tmp > broom->fdoor; tmp--) X doors[tmp] = doors[tmp-1]; X doorindex++; X doors[tmp].x = x; X doors[tmp].y = y; X for( ; broom->hx >= 0; broom++) broom->fdoor++; X} X Xstatic boolean Xplace_niche(aroom,dy,xx,yy) Xregister struct mkroom *aroom; Xint *dy, *xx, *yy; X{ X coord dd; X X if(rn2(2)) { X *dy = 1; X finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1); X } else { X *dy = -1; X finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1); X } X *xx = dd.x; X *yy = dd.y; X return(levl[*xx][(*yy)+(*dy)].typ == STONE); X} X X#ifdef ORACLE Xboolean Xplace_oracle(aroom,dy,xx,yy) Xregister struct mkroom *aroom; Xint *dy, *xx, *yy; X{ X if(!place_niche(aroom,dy,xx,yy)) return FALSE; X X dosdoor(*xx,*yy,aroom,DOOR); X levl[*xx][*yy].doormask = D_NODOOR; X return TRUE; X} X#endif X X/* there should be one of these per trap */ Xconst char *engravings[] = { "", "", "", "", "", "", X "?la? ?as ?er?", "ad ae?ar um", X "", "", "", "" ,"" X , "", "ad ae?ar um" X#ifdef SPELLS X ,"" X#endif X ,"" X#ifdef POLYSELF X ,"" X#endif X ,"" X }; X Xstatic void Xmakeniche(trap_type) Xint trap_type; X{ X register struct mkroom *aroom; X register struct rm *rm; X register int vct = 8; X int dy, xx, yy; X register struct trap *ttmp; X X if(doorindex < DOORMAX) X while(vct--) { X aroom = &rooms[rn2(nroom)]; X if(aroom->rtype != OROOM) continue; /* not an ordinary room */ X if(aroom->doorct == 1 && rn2(5)) continue; X if(!place_niche(aroom,&dy,&xx,&yy)) continue; X X rm = &levl[xx][yy+dy]; X if(trap_type || !rn2(4)) { X X rm->typ = SCORR; X rm->scrsym = ' '; /* _not_ STONE_SYM */ X if(trap_type) { X ttmp = maketrap(xx, yy+dy, trap_type); X ttmp->once = 1; X if (strlen(engravings[trap_type]) > 0) X make_engr_at(xx, yy-dy, engravings[trap_type]); X } X dosdoor(xx, yy, aroom, SDOOR); X } else { X rm->typ = CORR; X rm->scrsym = CORR_SYM; X if(rn2(7)) X dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); X else { X (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy); X if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE); X } X } X return; X } X} X Xstatic void Xmake_niches() X{ X register int ct = rnd((nroom>>1) + 1); X boolean ltptr = TRUE, X vamp = TRUE; X X while(ct--) { X X if(dlevel > 15 && !rn2(6) && ltptr) { X X ltptr = FALSE; X makeniche(LEVEL_TELEP); X } else if (dlevel > 5 && dlevel < 25 X && !rn2(6) && vamp) { X X vamp = FALSE; X makeniche(TRAPDOOR); X } else makeniche(NO_TRAP); X } X} X Xstatic void Xmakebigroom() X{ X register int x,y,n; X register struct mkroom *croom; X register struct monst *tmonst; X X /* make biggest possible room; make sure it's lit */ X (void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE); X croom = &rooms[0]; X X /* add extra monsters and goodies */ X n = 10 + rn2(15); X while (n--) { X x = somex(croom); X y = somey(croom); X tmonst = makemon((struct permonst *) 0,x,y); X if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER]) X (void) maketrap(x,y,WEB); X if (tmonst && rn2(2)) X tmonst->msleep = 1; X } X n = 6 + rn2(10); X while (n--) X (void) mkobj_at(0,somex(croom),somey(croom),TRUE); X} X Xstatic void Xmakevtele() X{ X makeniche(TELEP_TRAP); X} X X#define rntwixt(L1,L2) rn1((L2)-(L1),L1) X Xstatic void Xinit_levels() X{ X#if defined(STRONGHOLD) && defined(MUSIC) X register int x; X#endif X X#ifdef LINT /* handle constant in conditional context */ X medusa_level = 0; X#else X medusa_level = rn1(3, HELLLEVEL - 5); X#endif /* LINT */ X#ifdef STRONGHOLD X stronghold_level = rn1(5, medusa_level)+1; X# ifdef MUSIC X for (x=0; x<5; x++) X tune[x] = 'A' + rn2(7); X tune[5] = 0; X# endif X /* The tower will be on 3 levels */ X tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1; X /* We don't want the wizard in Vlad's tower */ X do X wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1; X while (wiz_level >= tower_level && wiz_level <= tower_level + 2); X#else X wiz_level = rntwixt(medusa_level, MAXLEVEL)+1; X#endif /* STRONGHOLD /**/ X#ifdef WIZARD X if (!rn2(15) || wizard) X#else X if (!rn2(15)) X#endif X /* between the middle of the dungeon and the medusa level */ X bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level); X#ifdef REINCARNATION X# ifdef WIZARD X if (!rn2(3) || wizard) X# else X if (!rn2(3)) X# endif X rogue_level = rn1(5,10); X#endif X#ifdef ORACLE X oracle_level = rn1(4,5); X#endif X} X X#undef rntwixt X Xstatic void Xmakelevel() { X register struct mkroom *croom, *troom; X register unsigned int tryct; X register int x,y; X struct monst *tmonst; /* always put a web with a spider */ X X nroom = 0; X doorindex = 0; X rooms[0].hx = -1; /* in case we are in a maze */ X X for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) { X levl[x][y] = zerorm; X level.objects[x][y] = (struct obj *)0; X level.monsters[x][y] = (struct monst *)0; X } X X oinit(); /* assign level dependent obj probabilities */ X fountsound = 0; X sinksound = 0; X X if (wiz_level == 0) X init_levels(); X if ( X#ifndef STRONGHOLD X Inhell X#else X dlevel >= stronghold_level || dlevel < 0 X#endif X || (dlevel > medusa_level && rn2(5)) X ) { X makemaz(); X return; X } X X /* construct the rooms */ X nroom = 0; X secret = FALSE; X X#ifdef REINCARNATION X if (dlevel == rogue_level) { X makeroguerooms(); X makerogueghost(); X } else X#endif X if (dlevel == bigroom_level) X makebigroom(); X else X (void) makerooms(); X X /* construct stairs (up and down in different rooms if possible) */ X croom = &rooms[rn2(nroom)]; X xdnstair = somex(croom); X ydnstair = somey(croom); X levl[xdnstair][ydnstair].scrsym = DN_SYM; X levl[xdnstair][ydnstair].typ = STAIRS; X#ifdef MEDUSA X if (dlevel == medusa_level) { X struct monst *mtmp; X struct obj *otmp; X X if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair)) X mtmp->msleep = 1; X for (tryct = rn1(1,3); tryct; tryct--) { X x = somex(croom); y = somey(croom); X if (goodpos(x,y,(struct permonst *)0)) { X otmp = mk_tt_object(STATUE, x, y); X while(otmp && X resists_ston(&mons[otmp->corpsenm])) { X otmp->corpsenm = rndmonnum(); X otmp->owt = weight(otmp); X } X } X } X } X#endif X if(nroom > 1) { X troom = croom; X croom = &rooms[rn2(nroom-1)]; X if(croom >= troom) croom++; X } X do { X xupstair = somex(croom); X yupstair = somey(croom); X } while(occupied(xupstair, yupstair)); X levl[xupstair][yupstair].scrsym = UP_SYM; X levl[xupstair][yupstair].typ = STAIRS; X#ifdef STRONGHOLD X xdnladder = ydnladder = xupladder = yupladder = 0; X#endif X is_maze_lev = FALSE; X X#if defined(SYSV) || defined(DGUX) X qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp); X#else X qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp); X#endif X#ifdef REINCARNATION X if (dlevel == rogue_level) { X You("feel as though you were here in a previous lifetime."); X goto skip0; X } X#endif X makecorridors(); X make_niches(); X X /* make a secret treasure vault, not connected to the rest */ X if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) { X X troom = &rooms[nroom]; X secret = TRUE; X if(makerooms()) { X troom->rtype = VAULT; /* treasure vault */ X for(x = troom->lx; x <= troom->hx; x++) X for(y = troom->ly; y <= troom->hy; y++) X mkgold((long)(rnd(dlevel*100) + 50), x, y); X if(!rn2(3)) X makevtele(); X } X } X X#ifdef WIZARD X if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else X#endif X#ifdef ORACLE X if(dlevel == oracle_level) mkroom(DELPHI); X /* It is possible that we find no good place to set up Delphi. X * It is also possible to get more than one Delphi using bones levels. X * The first is not a problem; the second is a minor nuisance. X */ X else X#endif X if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE); X else X#ifdef THRONES X if(dlevel > 4 && !rn2(6)) mkroom(COURT); X else X#endif X if(dlevel > 6 && !rn2(7)) mkroom(ZOO); X else X#ifdef ALTARS X if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE); X else X#endif X if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD)) X mkroom(BEEHIVE); X else X if(dlevel > 11 && !rn2(6)) mkroom(MORGUE); X else X#ifdef ARMY X if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD)) X mkroom(BARRACKS); X else X#endif X if(dlevel > 18 && !rn2(6)) mkroom(SWAMP); X X#ifdef REINCARNATION Xskip0: X#endif X /* for each room: put things inside */ X for(croom = rooms; croom->hx > 0; croom++) { X register boolean boxinlev = FALSE; X X if(croom->rtype != OROOM) continue; X X /* put a sleeping monster inside */ X /* Note: monster may be on the stairs. This cannot be X avoided: maybe the player fell through a trap door X while a monster was on the stairs. Conclusion: X we have to check for monsters on the stairs anyway. */ X X if(u.uhave_amulet || !rn2(3)) { X x = somex(croom); y = somey(croom); X tmonst = makemon((struct permonst *) 0, x,y); X if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]) X (void) maketrap (x,y,WEB); X } X /* put traps and mimics inside */ X goldseen = FALSE; X while(!rn2(8-(dlevel/6))) mktrap(0,0,croom); X if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom)); X#ifdef REINCARNATION X if (dlevel == rogue_level) goto skip_nonrogue; X#endif X#ifdef FOUNTAINS X if(!rn2(10)) mkfount(0,croom); X#endif X#ifdef SINKS X if(!rn2(60)) mksink(croom); X#endif X#ifdef ALTARS X if(!rn2(60)) mkaltar(croom); X#endif X /* put statues inside */ X#ifdef MEDUSA X if(!rn2(dlevel == medusa_level ? 1 : 20)) { X struct obj *otmp; X X if (!rn2(dlevel == medusa_level ? 2 : 50)) X otmp = mk_tt_object(STATUE, X somex(croom), somey(croom)); X else { X otmp = mkcorpstat(STATUE, (struct permonst *)0, X somex(croom), somey(croom)); X } X if (dlevel == medusa_level && otmp) { X /* Medusa statues don't contain books */ X otmp->spe = 0; X while(resists_ston(&mons[otmp->corpsenm])) { X otmp->corpsenm = rndmonnum(); X otmp->owt = weight(otmp); X } X } X } X#else X if(!rn2(20)) X (void) mkcorpstat(STATUE, (struct permonst *)0, X somex(croom), somey(croom)); X#endif X X /* put box/chest inside */ X if(!rn2(20) && !boxinlev) { X X boxinlev = TRUE; X (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, X somex(croom), somey(croom)); X } X X#ifdef REINCARNATION X skip_nonrogue: X#endif X if(!rn2(3)) { X (void) mkobj_at(0, somex(croom), somey(croom), TRUE); X tryct = 0; X while(!rn2(5)) { X if(++tryct > 100){ X Printf("tryct overflow4\n"); X break; X } X (void) mkobj_at(0, somex(croom), somey(croom), X TRUE); X } X } X } X} X Xvoid Xmklev() X{ X if(getbones()) return; X X in_mklev = TRUE; X makelevel(); X bound_digging(); X in_mklev = FALSE; X} X Xstatic boolean Xbydoor(x, y) Xregister xchar x, y; X{ X register boolean tmp1, tmp2; X X /* break up large expression to help some compilers */ X tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR || X IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR); X tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR || X IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR); X return(tmp1 || tmp2); X} X X/* see whether it is allowable to create a door at [x,y] */ Xint Xokdoor(x,y) Xregister xchar x, y; X{ X register boolean near_door = bydoor(x, y); X X return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) && X doorindex < DOORMAX && !near_door); X} X Xvoid Xdodoor(x,y,aroom) Xregister int x, y; Xregister struct mkroom *aroom; X{ X if(doorindex >= DOORMAX) { X impossible("DOORMAX exceeded?"); X return; X } X if(!okdoor(x,y) && nxcor) X return; X dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); X} X Xstatic boolean Xoccupied(x, y) Xregister xchar x, y; X{ X return(t_at(x, y) || levl[x][y].typ == STAIRS X#ifdef FOUNTAINS X || IS_FOUNTAIN(levl[x][y].typ) X#endif X#ifdef THRONES X || IS_THRONE(levl[x][y].typ) X#endif X#ifdef SINKS X || IS_SINK(levl[x][y].typ) X#endif X#ifdef ALTARS X || levl[x][y].typ == ALTAR X#endif X || is_pool(x,y) X ); X} X X/* make a trap somewhere (in croom if mazeflag = 0) */ Xvoid Xmktrap(num, mazeflag, croom) Xregister int num, mazeflag; Xregister struct mkroom *croom; X{ X register struct trap *ttmp; X register int kind,nomonst,nomimic,nospider, X#ifdef POLYSELF X nopoly, X#endif X nospikes, nolevltp, X nolandmine, X tryct = 0; X X xchar mx,my; X X#ifdef __GNULINT__ X kind = nomimic = 0; X#endif X if(!num || num >= TRAPNUM) { X nomonst = (dlevel < 4) ? 1 : 0; X nolevltp = (dlevel < 5) ? 1 : 0; X nospikes = (dlevel < 6) ? 1 : 0; X nospider = (dlevel < 7) ? 1 : 0; X#ifdef POLYSELF X nopoly = (dlevel < 6) ? 1 : 0; X#endif X nolandmine = (dlevel < 5) ? 1 : 0; X nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; X if((mons[PM_SMALL_MIMIC].geno & G_GENOD) && X (mons[PM_LARGE_MIMIC].geno & G_GENOD) && X (mons[PM_GIANT_MIMIC].geno & G_GENOD)) X nomimic = 1; X if(mons[PM_GIANT_SPIDER].geno & G_GENOD) X nospider = 1; X X do { X#ifdef REINCARNATION X if (dlevel==rogue_level) { X switch(rn2(7)) { X case 0: kind = BEAR_TRAP; break; X case 1: kind = ARROW_TRAP; break; X case 2: kind = DART_TRAP; break; X case 3: kind = TRAPDOOR; break; X case 4: kind = PIT; break; X case 5: kind = SLP_GAS_TRAP; break; X case 6: kind = RUST_TRAP; break; X } X } else X#endif X kind = rnd(TRAPNUM-1); X if((kind == MONST_TRAP && (nomonst && nomimic)) X || ((kind == WEB) && nospider) X || (kind == SPIKED_PIT && nospikes) X || (kind == LEVEL_TELEP && nolevltp) X#ifdef POLYSELF X || (kind == POLY_TRAP && nopoly) X#endif X || (kind == LANDMINE && nolandmine) X ) kind = NO_TRAP; X } while(kind == NO_TRAP); X } else kind = num; X X if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) { X register struct monst *mtmp; X X do { X if(++tryct > 200) return; X /* note: fakedoor maybe on actual door */ X if(rn2(2)){ X if(rn2(2)) mx = croom->hx+1; X else mx = croom->lx-1; X my = somey(croom); X } else { X if(rn2(2)) my = croom->hy+1; X else my = croom->ly-1; X mx = somex(croom); X } X } while X (MON_AT(mx, my)); X X if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) { X mtmp->mimic = 1; X mtmp->m_ap_type = M_AP_FURNITURE; X mtmp->mappearance = S_cdoor; X } X return; X } X X do { X if(++tryct > 200) X return; X if(mazeflag){ X coord mm; X mazexy(&mm); X mx = mm.x; X my = mm.y; X } else { X mx = somex(croom); X my = somey(croom); X } X } while(occupied(mx, my)); X X ttmp = maketrap(mx, my, kind); X if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my); X if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP) X ttmp->tseen = 1; X} X X#ifdef FOUNTAINS Xvoid Xmkfount(mazeflag,croom) Xregister struct mkroom *croom; Xregister int mazeflag; X{ X register xchar mx,my; X register int tryct = 0; X X do { X if(++tryct > 200) return; X if(mazeflag) { X coord mm; X mazexy(&mm); X mx = mm.x; X my = mm.y; X } else { X mx = somex(croom); X my = somey(croom); X } X } while(occupied(mx, my) || bydoor(mx, my)); X X /* Put a fountain at mx, my */ X levl[mx][my].typ = FOUNTAIN; X levl[mx][my].scrsym = FOUNTAIN_SYM; X X fountsound++; X} X#endif /* FOUNTAINS /**/ X X#ifdef SINKS Xstatic void Xmksink(croom) Xregister struct mkroom *croom; X{ X register xchar mx,my; X register int tryct = 0; X X do { X if(++tryct > 200) return; X mx = somex(croom); X my = somey(croom); X } while(occupied(mx, my) || bydoor(mx, my)); X X /* Put a sink at mx, my */ X levl[mx][my].typ = SINK; X levl[mx][my].scrsym = SINK_SYM; X X sinksound++; X} X#endif /* SINKS /**/ X X X#ifdef ALTARS Xstatic void Xmkaltar(croom) Xregister struct mkroom *croom; X{ X register xchar mx,my; X register int tryct = 0; X X if(croom->rtype != OROOM) return; X X do { X if(++tryct > 200) return; X mx = somex(croom); X my = somey(croom); X } while(occupied(mx, my) || bydoor(mx, my)); X X /* Put an altar at mx, my */ X levl[mx][my].typ = ALTAR; X levl[mx][my].scrsym = ALTAR_SYM; X /* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */ X levl[mx][my].altarmask = rn2((int)A_LAW+1); X} X#endif /* ALTARS /**/ END_OF_FILE if test 28964 -ne `wc -c <'src/mklev.c'`; then echo shar: \"'src/mklev.c'\" unpacked with wrong size! fi # end of 'src/mklev.c' fi if test -f 'src/monmove.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/monmove.c'\" else echo shar: Extracting \"'src/monmove.c'\" \(24074 characters\) sed "s/^X//" >'src/monmove.c' <<'END_OF_FILE' X/* SCCS Id: @(#)monmove.c 3.0 89/11/21 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#ifndef LINT /* comment line for pre-compiled headers */ X# ifndef __STDC__ /* comment line for pre-compiled headers */ X#define TRAP_H /* comment line for pre-compiled headers */ X/* block some unused #defines to avoid overloading some cpp's */ X# endif /* comment line for pre-compiled headers */ X#endif /* comment line for pre-compiled headers */ X X#include "hack.h" X#include "mfndpos.h" X#ifdef NAMED_ITEMS X# include "artifact.h" X#endif X X#ifdef OVL1 Xstatic void FDECL(distfleeck,(struct monst *,int *,int *,int *)); X#endif /* OVL1 */ X X#ifdef OVL0 X# ifdef POLYSELF Xstatic boolean FDECL(itsstuck,(struct monst *)); X# endif X#endif /* OVL0 */ X X#ifdef OVLB X Xboolean /* TRUE : mtmp died */ Xmb_trapped(mtmp) Xregister struct monst *mtmp; X{ X if (flags.verbose) { X if (cansee(mtmp->mx, mtmp->my)) X pline("KABOOM!! You see a door explode."); X else if (flags.soundok) X You("hear a distant explosion."); X } X mtmp->mstun = 1; X mtmp->mhp -= rnd(15); X if(mtmp->mhp <= 0) { X mondied(mtmp); X return(TRUE); X } X return(FALSE); X} X Xboolean Xmdig_tunnel(mtmp) /* FALSE: monster died */ Xregister struct monst *mtmp; X{ X register struct rm *here; X register int pile = rnd(12); X boolean canseeit = cansee(mtmp->mx, mtmp->my); X here = &levl[mtmp->mx][mtmp->my]; X X if (here->typ == SDOOR) X here->typ = DOOR; X if(IS_ROCK(here->typ)) { X /* Just ate something. */ X if(IS_WALL(here->typ)) { X if (!(here->diggable & W_NONDIGGABLE)) { X if(flags.soundok && flags.verbose && !rn2(5)) X You("hear the sound of crashing rock."); X if(!is_maze_lev) { X here->typ = DOOR; X here->doormask = D_NODOOR; X } X else X here->typ = ROOM; X } X } else X here->typ = CORR; X mnewsym(mtmp->mx, mtmp->my); X } else /* Eats away door if present & closed or locked */ X if(closed_door(mtmp->mx, mtmp->my)) { X if(here->doormask & D_TRAPPED) { X here->doormask = D_NODOOR; X if(mb_trapped(mtmp)) return(FALSE); X } else { X if(!rn2(3) && flags.verbose) X /* not too often.. */ X You("feel an unexpected draft of air."); X here->doormask = D_BROKEN; X } X mnewsym(mtmp->mx, mtmp->my); X } else X /* it doesn't leave rocks if it didn't dig */ X return TRUE; X X /* Left behind a pile? */ X if(pile < 5) { X if(pile == 1) X (void) mksobj_at(BOULDER, mtmp->mx, mtmp->my); X else X (void) mksobj_at(ROCK, mtmp->mx, mtmp->my); X } X here->seen = TRUE; /* required for newsym and mnewsym to work */ X if(canseeit && mtmp->minvis && !See_invisible) X newsym(mtmp->mx,mtmp->my); X else X mnewsym(mtmp->mx,mtmp->my); X if (!canseeit) X here->seen = FALSE; X return(TRUE); X} X X#endif /* OVLB */ X#ifdef OVL1 X Xint Xdochugw(mtmp) X register struct monst *mtmp; X{ X register int x = mtmp->mx; X register int y = mtmp->my; X register int rd = dochug(mtmp); X register int dd; X X if(!rd && !mtmp->mpeaceful && X (dd = dist(mtmp->mx,mtmp->my)) < dist(x,y) && X dd < 100 && !canseemon(mtmp)) { X#ifdef NAMED_ITEMS X /* Note: this assumes we only want to warn against the monster which X * the weapon does extra damage to, as there is no "monster which X * the weapon warns against" field. X */ X if(spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp->data,1)) X warnlevel = 100; X else X#endif X if (Warning && mtmp->m_lev > warnlevel) X warnlevel = mtmp->m_lev; X } X return(rd); X} X X#endif /* OVL1 */ X#ifdef OVL2 X Xboolean Xonscary(x, y, mtmp) Xint x, y; Xstruct monst *mtmp; X{ X /* Note: minotaurs must be immune to scare monster to avoid abuse X * from creating them and taking their wands, then polymorphing 60 X * or so wands to get wishing... X */ X if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee || X mtmp->data->mlet == S_HUMAN || mtmp->mpeaceful || X mtmp->data == &mons[PM_MINOTAUR]) X return(FALSE); X return( X#ifdef ELBERETH X sengr_at("Elbereth", x, y) || X#endif X sobj_at(SCR_SCARE_MONSTER, x, y) != (struct obj *)0); X} X X#endif /* OVL2 */ X#ifdef OVL1 X Xstatic void Xdistfleeck(mtmp,inrange,nearby,scared) Xregister struct monst *mtmp; Xint *inrange, *nearby, *scared; X{ X int seescaryx, seescaryy; X X *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= X (BOLT_LIM * BOLT_LIM)); X *nearby = monnear(mtmp, mtmp->mux, mtmp->muy); X X /* Note: if your image is displaced, the monster sees the Elbereth X * at your displaced position, thus never attacking your displaced X * position, but possibly attacking you by accident. If you are X * invisible, it sees the Elbereth at your real position, thus never X * running into you by accident but possibly attacking the spot X * where it guesses you are. X */ X if (Invis && !perceives(mtmp->data)) { X seescaryx = mtmp->mux; X seescaryy = mtmp->muy; X } else { X seescaryx = u.ux; X seescaryy = u.uy; X } X *scared = (*nearby && onscary(seescaryx, seescaryy, mtmp)); X X if(*scared && !mtmp->mflee) { X#ifdef POLYSELF X if (!sticks(uasmon)) X#endif X unstuck(mtmp); /* monster lets go when fleeing */ X mtmp->mflee = 1; X#ifdef STUPID X if (rn2(7)) X mtmp->mfleetim = rnd(10); X else X mtmp->mfleetim = rnd(100); X#else X mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100)); X#endif X } X X} X X/* returns 1 if monster died moving, 0 otherwise */ Xint Xdochug(mtmp) Xregister struct monst *mtmp; X{ X register struct permonst *mdat = mtmp->data; X register int tmp=0; X int inrange, nearby, scared; X X/* Pre-movement adjustments */ X X if(mtmp->cham && !rn2(6)) /* polymorph chameleons */ X (void) newcham(mtmp, (struct permonst *)0); X X /* regenerate monsters */ X if((!(moves%20) || regenerates(mdat)) && mtmp->mhp < mtmp->mhpmax) X mtmp->mhp++; X if(mtmp->mspec_used) mtmp->mspec_used--; X X /* polymorph lycanthropes */ X were_change(mtmp); X X if(!mtmp->mcanmove) { X if (Hallucination) pmon(mtmp); X return(0); /* frozen monsters don't do anything */ X } X X if(mtmp->msleep) /* there is a chance we will wake it */ X if(!disturb(mtmp)) return(0); X X /* not frozen or sleeping: wipe out texts written in the dust */ X wipe_engr_at(mtmp->mx, mtmp->my, 1); X X /* confused monsters get unconfused with small probability */ X if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0; X X /* stunned monsters get un-stunned with larger probability */ X if(mtmp->mstun && !rn2(10)) mtmp->mstun = 0; X X /* some monsters teleport */ X if(mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz) { X rloc(mtmp); X return(0); X } X if(mdat->mmove < rnd(6)) return(0); X X /* fleeing monsters might regain courage */ X if(mtmp->mflee && !mtmp->mfleetim X && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0; X X set_apparxy(mtmp); X /* Must be done after you move and before the monster does. The X * set_apparxy() call in m_move() doesn't suffice since the variables X * inrange, etc... all depend on stuff set by set_apparxy(). X */ X X /* The Wizard's prime directive */ X /* may teleport, so do it before inrange is set */ X if(mtmp->iswiz) X (void) wiz_get_amulet(mtmp); X X /* check distance and scariness of attacks */ X distfleeck(mtmp,&inrange,&nearby,&scared); X X#ifdef INFERNO /* Demonic Blackmail! */ X if(nearby && mdat->msound == MS_BRIBE && X mtmp->mpeaceful && !mtmp->mtame) { X if (mtmp->mux != u.ux || mtmp->muy != u.uy) { X pline("%s whispers something to thin air.", X cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It"); X# ifdef POLYSELF X if (is_demon(uasmon)) rloc(mtmp); X /* "Good hunting, brother" */ X else { X# endif X mtmp->minvis = 0; X /* Why? For the same reason in real demon talk */ X pline("%s gets angry.", Xmonnam(mtmp)); X mtmp->mpeaceful = 0; X /* since no way is an image going to pay it off */ X# ifdef POLYSELF X } X# endif X } else if(demon_talk(mtmp)) return(1); /* you paid it off */ X } X#endif X X/* Now the actual movement phase */ X X if(!nearby || mtmp->mflee || scared || X mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) || X (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) || X (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) || X (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) { X X tmp = m_move(mtmp, 0); X distfleeck(mtmp,&inrange,&nearby,&scared); /* recalc */ X X switch (tmp) { X X case 0: /* no movement, but it can still attack you */ X case 3: /* absolutely no movement */ X /* for pets, case 0 and 3 are equivalent */ X /* During hallucination, monster appearance should X * still change - even if it doesn't move. X */ X if(Hallucination) pmon(mtmp); X break; X case 1: /* monster moved */ X /* Maybe it stepped on a trap and fell asleep... */ X if(mtmp->msleep || !mtmp->mcanmove) return(0); X if(!nearby && ranged_attk(mdat)) break; X else if(mdat->mmove <= 12) return(0); X break; X case 2: /* monster died */ X return(1); X } X } X X/* Now, attack the player if possible - one attack set per monst */ X X if(inrange && !noattacks(mdat) && X !mtmp->mpeaceful && !mtmp->mtame && u.uhp > 0 && !scared && tmp != 3) X if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */ X X#ifdef WORM X if(mtmp->wormno && !mtmp->mtame) wormhit(mtmp); X#endif X X /* extra emotional attack for vile monsters */ X if(inrange && mtmp->data->msound == MS_CUSS && X !mtmp->minvis && !mtmp->mpeaceful && !rn2(5)) X cuss(mtmp); X X /* extra movement for fast monsters */ X if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp, 1); X return(tmp == 2); X} X Xstatic const char NEARDATA practical[] = { WEAPON_SYM, GEM_SYM, FOOD_SYM, 0 }; Xstatic const char NEARDATA magical[] = { X AMULET_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM, RING_SYM, X#ifdef SPELLS X SPBOOK_SYM, X#endif X 0 }; Xstatic const char NEARDATA indigestion[] = { BALL_SYM, ROCK_SYM, 0 }; X X#endif /* OVL1 */ X#ifdef OVL0 X X#ifdef POLYSELF Xstatic boolean Xitsstuck(mtmp) Xregister struct monst *mtmp; X{ X if (sticks(uasmon) && mtmp==u.ustuck && !u.uswallow) { X kludge("%s cannot escape from you!", Monnam(mtmp)); X return(TRUE); X } X return(FALSE); X} X#endif X Xint Xm_move(mtmp, after) Xregister struct monst *mtmp; Xregister int after; X{ X register struct monst *mtmp2; X register int nx,ny,omx,omy,appr,nearer,cnt,i,j; X xchar gx,gy,nix,niy,chcnt; X schar chi; X boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0; X boolean likerock=0, can_tunnel=0; X boolean can_open=0, can_unlock=0, doorbuster=0; X struct permonst *ptr = mtmp->data; X schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */ X coord poss[9]; X long info[9]; X long flag; X X if(mtmp->mtrapped) { X i = mintrap(mtmp); X if(i == 2) return(2); /* it died */ X if(i == 1) return(0); /* still in trap, so didn't move */ X } X if(mtmp->mhide && X (OBJ_AT(mtmp->mx, mtmp->my) || levl[mtmp->mx][mtmp->my].gmask) && X rn2(10)) X return(0); /* do not leave hiding place */ X if(mtmp->meating) { X mtmp->meating--; X return(3); /* still eating */ X } X X set_apparxy(mtmp); X /* where does mtmp think you are? */ X /* Not necessary if m_move called from this file, but necessary in X * other calls of m_move (ex. leprechauns dodging) X */ X can_tunnel = tunnels(ptr) && X#ifdef REINCARNATION X dlevel != rogue_level && X#endif X (!needspick(ptr) || m_carrying(mtmp, PICK_AXE)); X can_open = !(nohands(ptr) || verysmall(ptr)); X can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) || mtmp->iswiz); X doorbuster = is_giant(ptr); X#ifdef WORM X if(mtmp->wormno) goto not_special; X#endif X /* my dog gets special treatment */ X if(mtmp->mtame) { X mmoved = dog_move(mtmp, after); X goto postmov; X } X X /* likewise for shopkeeper */ X if(mtmp->isshk) { X mmoved = shk_move(mtmp); X if(mmoved == -2) return(2); X if(mmoved >= 0) goto postmov; X mmoved = 0; /* follow player outside shop */ X } X X /* and for the guard */ X if(mtmp->isgd) { X mmoved = gd_move(mtmp); X if(mmoved == -2) return(2); X if(mmoved >= 0) goto postmov; X mmoved = 0; X } X X /* and the wiz already got special treatment */ X if(mtmp->iswiz) { X mmoved = 0; X goto postmov; X } X#if defined(ALTARS) && defined(THEOLOGY) X /* and for the priest */ X if(mtmp->ispriest) { X mmoved = pri_move(mtmp); X if(mmoved == -2) return(2); X if(mmoved >= 0) goto postmov; X mmoved = 0; X } X#endif X#ifdef MAIL X if(ptr == &mons[PM_MAIL_DAEMON]) { X if(flags.soundok && canseemon(mtmp)) X verbalize("I'm late!"); X mongone(mtmp); X return(2); X } X#endif X /* teleport if that lies in our nature */ X if(ptr == &mons[PM_TENGU] && !rn2(5)) { X if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2)) X rloc(mtmp); X else X mnexto(mtmp); X mmoved = 1; X goto postmov; X } X#ifdef WORM Xnot_special: X#endif X if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1); X appr = 1; X if(mtmp->mflee) appr = -1; X if(mtmp->mconf || (Invis && !perceives(ptr)) || !mtmp->mcansee || X#ifdef POLYSELF X (u.usym == S_MIMIC_DEF) || u.uundetected || X#endif X (mtmp->mpeaceful && !mtmp->isshk) || /* allow shks to follow */ X ((ptr->mlet == S_STALKER || ptr->mlet == S_BAT || X ptr->mlet == S_YLIGHT) && !rn2(3))) X appr = 0; X omx = mtmp->mx; X omy = mtmp->my; X gx = mtmp->mux; X gy = mtmp->muy; X if(ptr == &mons[PM_LEPRECHAUN] && appr == 1 && mtmp->mgold > u.ugold) X appr = -1; X X if(can_track(ptr)) { X register coord *cp; X schar mroom; X X mroom = inroom(omx,omy); X if(mroom < 0 || mroom != inroom(u.ux,u.uy)){ X cp = gettrack(omx,omy); X if(cp){ X gx = cp->x; X gy = cp->y; X } X } X } X X#ifdef REINCARNATION X if (dlevel != rogue_level) X#endif X { X register int pctload = (curr_mon_load(mtmp) * 100) / X max_mon_load(mtmp); X X /* look for gold or jewels nearby */ X likegold = (likes_gold(ptr) && pctload < 95); X likegems = (likes_gems(ptr) && pctload < 85); X likeobjs = (likes_objs(ptr) && pctload < 75); X likemagic = (likes_magic(ptr) && pctload < 85); X likerock = (throws_rocks(ptr) && pctload < 50); X conceals = hides_under(ptr); X } X X#define SQSRCHRADIUS 5 X#define SRCHRADIUS (SQSRCHRADIUS*SQSRCHRADIUS) X X { xchar mind = SRCHRADIUS; /* not too far away */ X register int dd; X X /* cut down the search radius if it thinks character is closer. */ X if(dist2(mtmp->mux, mtmp->muy, omx, omy) < SRCHRADIUS && X !mtmp->mtame && !mtmp->mpeaceful) mind /= 2; X X if(likegold){ X register struct gold *gold; X X for(gold = fgold; gold; gold = gold->ngold) X if((dd = dist2(omx,omy,gold->gx,gold->gy)) < mind){ X mind = dd; X gx = gold->gx; X gy = gold->gy; X } X } X if((likegems || likeobjs || likemagic || likerock || conceals) X && (!in_shop(omx, omy) || (!rn2(25) && !mtmp->isshk))) { X register struct obj *otmp; X register int xx, yy; X X for(xx = omx-SQSRCHRADIUS; xx <= omx+SQSRCHRADIUS; xx++) { X for(yy = omy-SQSRCHRADIUS; yy <= omy+SQSRCHRADIUS; yy++) { X if(!isok(xx, yy)) continue; X if((dd = dist2(omx,omy,xx, yy)) >= mind) continue; X for(otmp = level.objects[xx][yy]; otmp; otmp = otmp->nexthere) X if((likeobjs && index(practical, otmp->olet)) || X (likemagic && index(magical, otmp->olet)) || X (likerock && otmp->otyp == BOULDER) || X (likegems && otmp->olet == GEM_SYM && X otmp->otyp < LAST_GEM + 6) || X (conceals && !cansee(otmp->ox,otmp->oy)) || X (ptr == &mons[PM_GELATINOUS_CUBE] && X !index(indigestion, otmp->olet)) X ) { X if(can_carry(mtmp,otmp)) X if(ptr->mlet != S_UNICORN || X objects[otmp->otyp].g_val != 0){ X mind = dd; X gx = otmp->ox; X gy = otmp->oy; X break; X } X } X } X } X } X if(mind < SRCHRADIUS && appr == -1) { X if(dist2(omx,omy,mtmp->mux,mtmp->muy) < 10) { X gx = mtmp->mux; X gy = mtmp->muy; X } else X appr = 1; X } X } X nix = omx; X niy = omy; X flag = ALLOW_TRAPS; X if (mtmp->mpeaceful) flag |= (ALLOW_SANCT | ALLOW_SSM); X else flag |= ALLOW_U; X if (ptr->mlet == S_UNICORN) flag |= NOTONL; X if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK); X if (can_tunnel) flag |= ALLOW_DIG; X if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) flag |= ALLOW_SSM; X if (is_undead(ptr)) flag |= NOGARLIC; X if (throws_rocks(ptr)) flag |= ALLOW_ROCK; X if (can_open) flag |= OPENDOOR; X if (can_unlock) flag |= UNLOCKDOOR; X if (doorbuster) flag |= BUSTDOOR; X cnt = mfndpos(mtmp, poss, info, flag); X chcnt = 0; X chi = -1; X X for(i=0; i < cnt; i++) { X nx = poss[i].x; X ny = poss[i].y; X X if (appr != 0) for(j=0; j < MTSZ && j < cnt-1; j++) X if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) X if(rn2(4*(cnt-j))) goto nxti; X X nearer = (dist2(nx,ny,gx,gy) < dist2(nix,niy,gx,gy)); X X if((appr == 1 && nearer) || (appr == -1 && !nearer) || X (!appr && !rn2(++chcnt)) || !mmoved) { X nix = nx; X niy = ny; X chi = i; X mmoved = 1; X } X nxti: ; X } X X if(mmoved) { X#ifdef POLYSELF X if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp)) X return(3); X#endif X if((info[chi] & ALLOW_U) || (nix == u.ux && niy == u.uy)) { X mtmp->mux = u.ux; X mtmp->muy = u.uy; X return(0); X } X /* The monster may attack another based on 1 of 2 conditions: X * 1 - He may be under the "conflict" influence. X * 2 - He may mistake the monster for your (displaced) image. X * Pets get taken care of above and shouldn't reach this code. X */ X if((info[chi] & ALLOW_M) || X (nix == mtmp->mux && niy == mtmp->muy)) { X int stat; X mtmp2 = m_at(nix,niy); X if((stat = mattackm(mtmp, mtmp2)) == 1 && rn2(4) && X mtmp2->mlstmv != moves && mattackm(mtmp2, mtmp) == 2) X return(2); X if(stat == -1) return(2); X return(3); X } X#ifdef WORM X /* The square now has a worm segment and must keep its MON_AT() state */ X if (!mtmp->wormno) X#endif X remove_monster(omx, omy); X place_monster(mtmp, nix, niy); X for(j = MTSZ-1; j > 0; j--) X mtmp->mtrack[j] = mtmp->mtrack[j-1]; X mtmp->mtrack[0].x = omx; X mtmp->mtrack[0].y = omy; X#ifdef WORM X if(mtmp->wormno) worm_move(mtmp); X#endif X } else { X if(ptr->mlet == S_UNICORN && rn2(2)) { X rloc(mtmp); X return(1); X } X#ifdef WORM X if(mtmp->wormno) worm_nomove(mtmp); X#endif X } Xpostmov: X if(mmoved == 1) { X boolean canseeit = cansee(mtmp->mx, mtmp->my); X boolean abstain = (mtmp->mpeaceful && !mtmp->mtame); X X if(mintrap(mtmp) == 2) return(2); /* he died */ X X /* open a door, or crash through it, if you can */ X if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ) X && !passes_walls(ptr) /* doesn't need to open doors */ X && !can_tunnel /* taken care of below */ X ) { X struct rm *here = &levl[mtmp->mx][mtmp->my]; X boolean btrapped = (here->doormask & D_TRAPPED); X X if(here->doormask & (D_LOCKED|D_CLOSED) && amorphous(ptr)) { X if (flags.verbose && canseeit) X pline("%s %ss under the door.", Monnam(mtmp), X ptr == &mons[PM_FOG_CLOUD] ? "flow" : "ooze"); X } else if(here->doormask & D_LOCKED && can_unlock) { X if(btrapped) { X here->doormask = D_NODOOR; X mnewsym(mtmp->mx, mtmp->my); X if (canseeit) prl(mtmp->mx,mtmp->my); X if(mb_trapped(mtmp)) return(2); X } else { X if (flags.verbose) { X if (canseeit) X You("see a door being unlocked and opened."); X else if (flags.soundok) X You("hear a door being unlocked and opened."); X } X here->doormask = D_ISOPEN; X mnewsym(mtmp->mx, mtmp->my); X if (canseeit) prl(mtmp->mx,mtmp->my); X } X } else if (here->doormask == D_CLOSED && can_open) { X if(btrapped) { X here->doormask = D_NODOOR; X mnewsym(mtmp->mx, mtmp->my); X if (canseeit) prl(mtmp->mx,mtmp->my); X if(mb_trapped(mtmp)) return(2); X } else { X if (flags.verbose) { X if (canseeit) X You("see a door being opened."); X else if (flags.soundok) X You("hear the sound of a door opening."); X } X here->doormask = D_ISOPEN; X mnewsym(mtmp->mx, mtmp->my); X if (canseeit) prl(mtmp->mx,mtmp->my); X } X } else if (here->doormask & (D_LOCKED|D_CLOSED)) { X /* mfndpos guarantees this must be a doorbuster */ X if(btrapped) { X here->doormask = D_NODOOR; X mnewsym(mtmp->mx, mtmp->my); X if (canseeit) prl(mtmp->mx,mtmp->my); X if(mb_trapped(mtmp)) return(2); X } else { X if (flags.verbose) { X if (canseeit) X You("see a door crash open."); X else if (flags.soundok) X You("hear the sound of a door crashing open."); X } X if (here->doormask & D_LOCKED && !rn2(2)) X here->doormask = D_NODOOR; X else here->doormask = D_BROKEN; X mnewsym(mtmp->mx, mtmp->my); X if (canseeit) prl(mtmp->mx,mtmp->my); X } X } X } X /* Maybe a rock mole just ate something? */ X if(can_tunnel) if(!mdig_tunnel(mtmp)) return(2); /* died? */ X X if(levl[mtmp->mx][mtmp->my].gmask == TRUE) { X /* Maybe a rock mole just ate some gold */ X if(metallivorous(ptr)) meatgold(mtmp); X if(likegold && (!abstain || !rn2(10))) mpickgold(mtmp); X } X if(OBJ_AT(mtmp->mx, mtmp->my)) { X /* Maybe a rock mole just ate some metal object */ X if(metallivorous(ptr)) meatgold(mtmp); X /* Maybe a cube ate just about anything */ X if(ptr == &mons[PM_GELATINOUS_CUBE]) meatobj(mtmp); X X if ((!abstain || !rn2(10)) X && (!in_shop(mtmp->mx, mtmp->my) || !rn2(25))) { X if(likeobjs) mpickstuff(mtmp, practical); X if(likemagic) mpickstuff(mtmp, magical); X if(likerock || likegems) mpickgems(mtmp); X } X } X if(mtmp->mhide) mtmp->mundetected = (OBJ_AT(mtmp->mx, mtmp->my) X || levl[mtmp->mx][mtmp->my].gmask); X X /* set also in domove(), hack.c */ X if(u.uswallow && mtmp == u.ustuck) { X u.ux = mtmp->mx; X u.uy = mtmp->my; X if(mtmp->mx != mtmp->mdx || mtmp->my != mtmp->mdy) { X swallowed(0); X newsym(mtmp->mdx,mtmp->mdy); X mtmp->mdx = mtmp->mx; X mtmp->mdy = mtmp->my; X } X } X pmon(mtmp); X } X return(mmoved); X} X X#endif /* OVL0 */ X#ifdef OVL2 X Xboolean Xclosed_door(x, y) Xregister int x, y; X{ X return(IS_DOOR(levl[x][y].typ) && X (levl[x][y].doormask & (D_LOCKED | D_CLOSED))); X} X Xboolean Xaccessible(x, y) Xregister int x, y; X{ X return(ACCESSIBLE(levl[x][y].typ) && !closed_door(x, y)); X} X X#endif /* OVL2 */ X#ifdef OVL1 X Xvoid Xset_apparxy(mtmp) /* where does mtmp think you are standing? */ X register struct monst *mtmp; X{ X#define notseen (Invis && !perceives(mtmp->data)) X/* add cases as required. eg. Displacement ... */ X register int disp = (notseen ? 1 : Displaced ? 2 : 0); X X/* without something like the following, invis. and displ. are too */ X/* powerful. */ X register boolean gotu = X (notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE); X X/* Monsters which know where you are don't suddenly forget, if you X didn't move away. */ X if (mtmp->mux==u.ux && mtmp->muy==u.uy) gotu = 1; X X/* your dog follows your smell */ X if(!disp || mtmp->mtame || gotu || X/* If invisible but not displaced, staying around gets you 'discovered' */ X (!Displaced && u.dx == 0 && u.dy == 0)) { X mtmp->mux = u.ux; X mtmp->muy = u.uy; X } X else do { X mtmp->mux = u.ux - disp + rn2(2*disp+1); X mtmp->muy = u.uy - disp + rn2(2*disp+1); X } while((mtmp->mux != u.ux || mtmp->muy != u.uy) && X ( (!passes_walls(mtmp->data) && X (!ACCESSIBLE(levl[mtmp->mux][mtmp->muy].typ) || X (closed_door(mtmp->mux, mtmp->muy) && X !amorphous(mtmp->data) X ) X ) X ) || X (disp==1 && mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my) X ) X ); X} X X#endif /* OVL1 */ X#ifdef OVLB X X#ifdef STUPID_CPP /* otherwise these functions are macros in rm.h */ X/* X * Functions for encapsulation of level.monsters references. X */ Xboolean XMON_AT(x, y) Xint x, y; X{ X return(level.monsters[x][y] != (struct monst *)0); X} X Xvoid place_monster(mtmp, x, y) Xregister struct monst *mtmp; Xint x, y; X{ X level.monsters[x][y] = mtmp; X mtmp->mx = x; X mtmp->my = y; X} X Xvoid place_worm_seg(mtmp, x, y) Xregister struct monst *mtmp; Xint x, y; X{ X level.monsters[x][y] = mtmp; X} X Xvoid remove_monster(x, y) Xint x, y; X{ X level.monsters[x][y] = (struct monst *)0; X} X Xstruct monst *m_at(x, y) Xint x, y; X{ X return(level.monsters[x][y]); X} X#endif /* STUPID_CPP */ X X#endif /* OVLB */ END_OF_FILE if test 24074 -ne `wc -c <'src/monmove.c'`; then echo shar: \"'src/monmove.c'\" unpacked with wrong size! fi # end of 'src/monmove.c' fi if test -f 'src/rip.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/rip.c'\" else echo shar: Extracting \"'src/rip.c'\" \(2319 characters\) sed "s/^X//" >'src/rip.c' <<'END_OF_FILE' X/* SCCS Id: @(#)rip.c 3.0 88/04/27 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X Xstatic void FDECL(center,(int,char *)); X Xstatic const char *rip_txt[] = { X" ----------", X" / \\", X" / REST \\", X" / IN \\", X" / PEACE \\", X" / \\", X" | |", X" | |", X" | |", X" | |", X" | |", X" | 1001 |", X" *| * * * | *", X" _________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n", X0 X}; X Xchar **rip; X Xstatic void Xcenter(line, text) Xint line; Xchar *text; X{ X register char *ip,*op; X ip = text; X op = &rip[line][28 - ((strlen(text)+1)>>1)]; X while(*ip) *op++ = *ip++; X} X Xvoid Xoutrip(){ X register char **dp; X register char *dpx; X char buf[BUFSZ]; X register int x, y; X int killed_by_line = 0; X X rip = dp = (char **) alloc(sizeof(rip_txt)); X if (!dp) return; X for (x = 0; rip_txt[x]; x++) { X dp[x] = (char *) alloc((unsigned int)(strlen(rip_txt[x]) + 1)); X if (!dp[x]) return; X Strcpy(dp[x], rip_txt[x]); X } X dp[x] = (char *)0; X X cls(); X Sprintf(buf, "%s", plname); X buf[16] = 0; X center(6, buf); X Sprintf(buf, "%ld Au", u.ugold); X center(7, buf); X if (killer_format != NO_KILLER_PREFIX) { X killed_by_line = 1; X Strcpy(buf, "killed by"); X if (killer_format == KILLED_BY_AN) X Strcat(buf, index(vowels, *killer) ? " an" : " a"); X center(8, buf); X } X Strcpy(buf, killer); X if(strlen(buf) > 16) { X register int i,i0,i1; X i0 = i1 = 0; X for(i = 0; i <= 16; i++) X if(buf[i] == ' ') i0 = i, i1 = i+1; X if(!i0) i0 = i1 = 16; X buf[i1 + 16] = 0; X center(9 + killed_by_line, buf+i1); X buf[i0] = 0; X } X center(8 + killed_by_line, buf); X Sprintf(buf, "%4d", getyear()); X center(11, buf); X for(y=8; *dp; y++,dp++){ X x = 0; X dpx = *dp; X while(dpx[x]) { X while(dpx[x] == ' ') x++; X curs(x,y); X while(dpx[x] && dpx[x] != ' '){ X if(done_stopprint) X return; X curx++; X (void) putchar(dpx[x++]); X } X } X } X getret(); X} X END_OF_FILE if test 2319 -ne `wc -c <'src/rip.c'`; then echo shar: \"'src/rip.c'\" unpacked with wrong size! fi # end of 'src/rip.c' fi echo shar: End of archive 32 \(of 56\). cp /dev/null ark32isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 56 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0