home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume10
/
nethack3p9
/
part32
< prev
next >
Wrap
Internet Message Format
|
1990-07-27
|
60KB
Path: uunet!clyde.concordia.ca!news-server.csri.toronto.edu!cs.utexas.edu!rice!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v10i077: nethack3p9 - display oriented dungeons & dragons (Ver. 3.0i), Part32/56
Message-ID: <5935@tekred.CNA.TEK.COM>
Date: 12 Jul 90 16:06:35 GMT
Sender: news@tekred.CNA.TEK.COM
Lines: 2326
Approved: billr@saab.CNA.TEK.COM
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