home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume10 / nethack3p9 / part32 < prev    next >
Internet Message Format  |  1990-07-27  |  60KB

  1. Path: uunet!clyde.concordia.ca!news-server.csri.toronto.edu!cs.utexas.edu!rice!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v10i077:  nethack3p9 -  display oriented dungeons & dragons (Ver. 3.0i), Part32/56
  5. Message-ID: <5935@tekred.CNA.TEK.COM>
  6. Date: 12 Jul 90 16:06:35 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2326
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 10, Issue 77
  13. Archive-name: nethack3p9/Part32
  14. Supersedes: NetHack3: Volume 7, Issue 56-93
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 32 (of 56)."
  25. # Contents:  src/mklev.c src/monmove.c src/rip.c
  26. # Wrapped by billr@saab on Wed Jul 11 17:11:39 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'src/mklev.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'src/mklev.c'\"
  30. else
  31. echo shar: Extracting \"'src/mklev.c'\" \(28964 characters\)
  32. sed "s/^X//" >'src/mklev.c' <<'END_OF_FILE'
  33. X/*    SCCS Id: @(#)mklev.c    3.0    89/12/06
  34. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  35. X/* NetHack may be freely redistributed.  See license for details. */
  36. X
  37. X#include "hack.h"
  38. X
  39. X/* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
  40. X/* croom->lx etc are schar (width <= int), so % arith ensures that */
  41. X/* conversion of result to int is reasonable */
  42. X
  43. X#ifdef SINKS
  44. Xstatic void FDECL(mksink,(struct mkroom *));
  45. X#endif
  46. X#ifdef ALTARS
  47. Xstatic void FDECL(mkaltar,(struct mkroom *));
  48. X#endif
  49. Xstatic boolean FDECL(occupied,(XCHAR_P,XCHAR_P));
  50. Xstatic void NDECL(makevtele);
  51. Xstatic void NDECL(init_levels);
  52. Xstatic void NDECL(makelevel);
  53. Xstatic boolean FDECL(bydoor,(XCHAR_P,XCHAR_P));
  54. Xstatic boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*));
  55. Xstatic void FDECL(makeniche,(int));
  56. Xstatic void NDECL(make_niches);
  57. Xstatic void NDECL(makebigroom);
  58. Xstatic void FDECL(addrsx,(int,int,int,int,BOOLEAN_P));
  59. Xstatic void FDECL(addrs,(int,int,int,int));
  60. XSTATIC_PTR int FDECL(comp,(genericptr_t,genericptr_t));
  61. Xstatic void FDECL(dosdoor,(int,int,struct mkroom *,int));
  62. Xstatic void NDECL(makecorridors);
  63. Xstatic void FDECL(join,(int,int));
  64. Xstatic int NDECL(makerooms);
  65. Xstatic int FDECL(maker,(SCHAR_P,SCHAR_P,SCHAR_P,SCHAR_P,BOOLEAN_P));
  66. Xstatic void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P));
  67. X
  68. Xint
  69. Xsomex(croom)
  70. Xregister struct mkroom *croom;
  71. X{
  72. X    return rn2(croom->hx-croom->lx+1) + croom->lx;
  73. X}
  74. X
  75. Xint
  76. Xsomey(croom)
  77. Xregister struct mkroom *croom;
  78. X{
  79. X    return rn2(croom->hy-croom->ly+1) + croom->ly;
  80. X}
  81. X
  82. X#define    XLIM    4    /* define minimum required space around a room */
  83. X#define    YLIM    3
  84. Xboolean secret;        /* TRUE while making a vault: increase [XY]LIM */
  85. Xstruct rm zerorm;
  86. Xschar nxcor;
  87. Xboolean goldseen;
  88. X
  89. X/* Definitions used by makerooms() and addrs() */
  90. X#define    MAXRS    50    /* max lth of temp rectangle table - arbitrary */
  91. Xstruct rectangle {
  92. X    xchar rlx,rly,rhx,rhy;
  93. X} rs[MAXRS+1];
  94. Xint rscnt,rsmax;    /* 0..rscnt-1: currently under consideration */
  95. X            /* rscnt..rsmax: discarded */
  96. X
  97. Xstatic void
  98. Xaddrsx(lx,ly,hx,hy,discarded)
  99. Xregister int lx,ly,hx,hy;
  100. Xboolean discarded;        /* piece of a discarded area */
  101. X{
  102. X    register struct rectangle *rsp;
  103. X
  104. X    /* check inclusions */
  105. X    for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
  106. X        if(lx >= rsp->rlx && hx <= rsp->rhx &&
  107. X           ly >= rsp->rly && hy <= rsp->rhy)
  108. X            return;
  109. X    }
  110. X
  111. X    /* make a new entry */
  112. X    if(rsmax >= MAXRS) {
  113. X#ifdef WIZARD
  114. X        if(wizard) pline("MAXRS may be too small.");
  115. X#endif
  116. X        return;
  117. X    }
  118. X    rsmax++;
  119. X    if(!discarded) {
  120. X        *rsp = rs[rscnt];
  121. X        rsp = &rs[rscnt];
  122. X        rscnt++;
  123. X    }
  124. X    rsp->rlx = lx;
  125. X    rsp->rly = ly;
  126. X    rsp->rhx = hx;
  127. X    rsp->rhy = hy;
  128. X}
  129. X
  130. Xstatic void
  131. Xaddrs(lowx,lowy,hix,hiy)
  132. Xregister int lowx,lowy,hix,hiy;
  133. X{
  134. X    register struct rectangle *rsp;
  135. X    register int lx,ly,hx,hy,xlim,ylim;
  136. X    boolean discarded;
  137. X
  138. X    xlim = XLIM + secret;
  139. X    ylim = YLIM + secret;
  140. X
  141. X    /* walk down since rscnt and rsmax change */
  142. X    for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
  143. X
  144. X        if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
  145. X           (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
  146. X            continue;
  147. X        if((discarded = (rsp >= &rs[rscnt]))) {
  148. X            *rsp = rs[--rsmax];
  149. X        } else {
  150. X            rsmax--;
  151. X            rscnt--;
  152. X            *rsp = rs[rscnt];
  153. X            if(rscnt != rsmax)
  154. X                rs[rscnt] = rs[rsmax];
  155. X        }
  156. X        if(lowy - ly > 2*ylim + 4)
  157. X            addrsx(lx,ly,hx,lowy-2,discarded);
  158. X        if(lowx - lx > 2*xlim + 4)
  159. X            addrsx(lx,ly,lowx-2,hy,discarded);
  160. X        if(hy - hiy > 2*ylim + 4)
  161. X            addrsx(lx,hiy+2,hx,hy,discarded);
  162. X        if(hx - hix > 2*xlim + 4)
  163. X            addrsx(hix+2,ly,hx,hy,discarded);
  164. X    }
  165. X}
  166. X
  167. X/* Args must be genericptr_t so that qsort will always be happy. */
  168. X
  169. XSTATIC_PTR int
  170. Xcomp(vx,vy)
  171. Xgenericptr_t vx;
  172. Xgenericptr_t vy;
  173. X{
  174. X#ifdef LINT
  175. X/* lint complains about possible pointer alignment problems, but we know
  176. X   that vx and vy are always properly aligned. Hence, the following
  177. X   bogus definition:
  178. X*/
  179. X    return (vx == vy) ? 0 : -1;
  180. X#else
  181. X    register struct mkroom *x, *y;
  182. X
  183. X    x = (struct mkroom *)vx;
  184. X    y = (struct mkroom *)vy;
  185. X    if(x->lx < y->lx) return(-1);
  186. X    return(x->lx > y->lx);
  187. X#endif /* LINT */
  188. X}
  189. X
  190. Xstatic void
  191. Xfinddpos(cc, xl,yl,xh,yh)
  192. Xcoord    *cc;
  193. Xxchar    xl,yl,xh,yh;
  194. X{
  195. X    register xchar x, y;
  196. X
  197. X    x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
  198. X    y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
  199. X    if(okdoor(x, y))
  200. X        goto gotit;
  201. X
  202. X    for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  203. X        if(okdoor(x, y))
  204. X            goto gotit;
  205. X
  206. X    for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
  207. X        if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
  208. X            goto gotit;
  209. X    /* cannot find something reasonable -- strange */
  210. X    x = xl;
  211. X    y = yh;
  212. Xgotit:
  213. X    cc->x = x;
  214. X    cc->y = y;
  215. X    return;
  216. X}
  217. X
  218. X/* Only called from makerooms() and makebigroom() */
  219. Xstatic int
  220. Xmaker(lowx,ddx,lowy,ddy,lit)
  221. Xschar lowx,ddx,lowy,ddy;
  222. Xboolean lit;
  223. X{
  224. X    register struct mkroom *croom;
  225. X    register int x, y, hix = lowx+ddx, hiy = lowy+ddy;
  226. X    register int xlim = XLIM + secret, ylim = YLIM + secret;
  227. X
  228. X    if(nroom >= MAXNROFROOMS) return(0);
  229. X    if(lowx < XLIM) lowx = XLIM;
  230. X    if(lowy < YLIM) lowy = YLIM;
  231. X    if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
  232. X    if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
  233. Xchk:
  234. X    if(hix <= lowx || hiy <= lowy) return(0);
  235. X
  236. X    /* check area around room (and make room smaller if necessary) */
  237. X    for(x = lowx - xlim; x <= hix + xlim; x++) {
  238. X        for(y = lowy - ylim; y <= hiy + ylim; y++) {
  239. X            if(isok(x,y) && levl[x][y].typ) {
  240. X#ifdef WIZARD
  241. X                if(wizard && !secret)
  242. X                pline("Strange area [%d,%d] in maker().",x,y);
  243. X#endif
  244. X                if(!rn2(3)) return(0);
  245. X                if(x < lowx)
  246. X                    lowx = x+xlim+1;
  247. X                else
  248. X                    hix = x-xlim-1;
  249. X                if(y < lowy)
  250. X                    lowy = y+ylim+1;
  251. X                else
  252. X                    hiy = y-ylim-1;
  253. X                goto chk;
  254. X            }
  255. X        }
  256. X    }
  257. X
  258. X    croom = &rooms[nroom];
  259. X
  260. X    /* on low levels the room is lit (usually) */
  261. X    /* secret vaults are always lit */
  262. X    /* some other rooms may require lighting */
  263. X    if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) {
  264. X        for(x = lowx-1; x <= hix+1; x++)
  265. X            for(y = lowy-1; y <= hiy+1; y++)
  266. X                levl[x][y].lit = 1;
  267. X        croom->rlit = 1;
  268. X    } else
  269. X        croom->rlit = 0;
  270. X    croom->lx = lowx;
  271. X    croom->hx = hix;
  272. X    croom->ly = lowy;
  273. X    croom->hy = hiy;
  274. X    croom->rtype = OROOM;
  275. X    croom->doorct = 0;
  276. X    /* if we're not making a vault, doorindex will still be 0
  277. X     * if we are, we'll have problems adding niches to the previous room
  278. X     * unless fdoor is at least doorindex
  279. X     */
  280. X    croom->fdoor = doorindex;
  281. X
  282. X    for(x = lowx-1; x <= hix+1; x++)
  283. X        for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
  284. X        levl[x][y].typ = HWALL;
  285. X        levl[x][y].scrsym = HWALL_SYM;
  286. X        }
  287. X    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
  288. X        for(y = lowy; y <= hiy; y++) {
  289. X        levl[x][y].typ = VWALL;
  290. X        levl[x][y].scrsym = VWALL_SYM;
  291. X        }
  292. X    for(x = lowx; x <= hix; x++)
  293. X        for(y = lowy; y <= hiy; y++) {
  294. X        levl[x][y].typ = ROOM;
  295. X        levl[x][y].scrsym = ROOM_SYM;
  296. X        }
  297. X    levl[lowx-1][lowy-1].typ = TLCORNER;
  298. X    levl[hix+1][lowy-1].typ = TRCORNER;
  299. X    levl[lowx-1][hiy+1].typ = BLCORNER;
  300. X    levl[hix+1][hiy+1].typ = BRCORNER;
  301. X    levl[lowx-1][lowy-1].scrsym = TLCORN_SYM;
  302. X    levl[hix+1][lowy-1].scrsym = TRCORN_SYM;
  303. X    levl[lowx-1][hiy+1].scrsym = BLCORN_SYM;
  304. X    levl[hix+1][hiy+1].scrsym = BRCORN_SYM;
  305. X
  306. X    smeq[nroom] = nroom;
  307. X    croom++;
  308. X    croom->hx = -1;
  309. X    nroom++;
  310. X    return(1);
  311. X}
  312. X
  313. Xstatic int
  314. Xmakerooms() {
  315. Xregister struct rectangle *rsp;
  316. Xregister int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
  317. Xint tryct = 0, xlim, ylim;
  318. X
  319. X    /* init */
  320. X    xlim = XLIM + secret;
  321. X    ylim = YLIM + secret;
  322. X    if(nroom == 0) {
  323. X        rsp = rs;
  324. X        rsp->rlx = rsp->rly = 0;
  325. X        rsp->rhx = COLNO-1;
  326. X        rsp->rhy = ROWNO-1;
  327. X        rsmax = 1;
  328. X    }
  329. X    rscnt = rsmax;
  330. X
  331. X    /* make rooms until satisfied */
  332. X    while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
  333. X        if(!secret && nroom > (MAXNROFROOMS/4) &&
  334. X           !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
  335. X            return 0;
  336. X
  337. X        /* pick a rectangle */
  338. X        rsp = &rs[rn2(rscnt)];
  339. X        hx = rsp->rhx;
  340. X        hy = rsp->rhy;
  341. X        lx = rsp->rlx;
  342. X        ly = rsp->rly;
  343. X
  344. X        /* find size of room */
  345. X        if(secret)
  346. X            dx = dy = 1;
  347. X        else {
  348. X            dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
  349. X            dy = 2 + rn2(4);
  350. X            if(dx*dy > 50)
  351. X                dy = 50/dx;
  352. X        }
  353. X
  354. X        /* look whether our room will fit */
  355. X        if(hx-lx < dx + (dx>>1) + 2*xlim ||
  356. X           hy-ly < dy + dy/3 + 2*ylim) {
  357. X                    /* no, too small */
  358. X                    /* maybe we throw this area out */
  359. X            if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
  360. X                rscnt--;
  361. X                rs[rsmax] = *rsp;
  362. X                *rsp = rs[rscnt];
  363. X                rs[rscnt] = rs[rsmax];
  364. X                tryct = 0;
  365. X            } else
  366. X                tryct++;
  367. X            continue;
  368. X        }
  369. X
  370. X        lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
  371. X        lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
  372. X        hix = lowx + dx;
  373. X        hiy = lowy + dy;
  374. X
  375. X        if(maker(lowx, dx, lowy, dy, FALSE)) {
  376. X            if(secret) return(1);
  377. X            addrs(lowx-1, lowy-1, hix+1, hiy+1);
  378. X            tryct = 0;
  379. X        } else
  380. X            if(tryct++ > 100)
  381. X                break;
  382. X    }
  383. X    return(0);    /* failed to make vault - very strange */
  384. X}
  385. X
  386. Xstatic void
  387. Xjoin(a,b)
  388. Xregister int a, b;
  389. X{
  390. X    coord cc,tt;
  391. X    register int tx, ty, xx, yy;
  392. X    register struct rm *crm;
  393. X    register struct mkroom *croom, *troom;
  394. X    register int dx, dy, dix, diy, cct;
  395. X
  396. X    croom = &rooms[a];
  397. X    troom = &rooms[b];
  398. X
  399. X    /* find positions cc and tt for doors in croom and troom
  400. X       and direction for a corridor between them */
  401. X
  402. X    if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
  403. X    if(troom->lx > croom->hx) {
  404. X        dx = 1;
  405. X        dy = 0;
  406. X        xx = croom->hx+1;
  407. X        tx = troom->lx-1;
  408. X        finddpos(&cc, xx, croom->ly, xx, croom->hy);
  409. X        finddpos(&tt, tx, troom->ly, tx, troom->hy);
  410. X    } else if(troom->hy < croom->ly) {
  411. X        dy = -1;
  412. X        dx = 0;
  413. X        yy = croom->ly-1;
  414. X        finddpos(&cc, croom->lx, yy, croom->hx, yy);
  415. X        ty = troom->hy+1;
  416. X        finddpos(&tt, troom->lx, ty, troom->hx, ty);
  417. X    } else if(troom->hx < croom->lx) {
  418. X        dx = -1;
  419. X        dy = 0;
  420. X        xx = croom->lx-1;
  421. X        tx = troom->hx+1;
  422. X        finddpos(&cc, xx, croom->ly, xx, croom->hy);
  423. X        finddpos(&tt, tx, troom->ly, tx, troom->hy);
  424. X    } else {
  425. X        dy = 1;
  426. X        dx = 0;
  427. X        yy = croom->hy+1;
  428. X        ty = troom->ly-1;
  429. X        finddpos(&cc, croom->lx, yy, croom->hx, yy);
  430. X        finddpos(&tt, troom->lx, ty, troom->hx, ty);
  431. X    }
  432. X    xx = cc.x;
  433. X    yy = cc.y;
  434. X    tx = tt.x - dx;
  435. X    ty = tt.y - dy;
  436. X    if(nxcor && levl[xx+dx][yy+dy].typ)
  437. X        return;
  438. X    dodoor(xx,yy,croom);
  439. X
  440. X    cct = 0;
  441. X    while(xx != tx || yy != ty) {
  442. X        xx += dx;
  443. X        yy += dy;
  444. X
  445. X        /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
  446. X        if(cct++ > 500 || (nxcor && !rn2(35)))
  447. X        return;
  448. X
  449. X        if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
  450. X        return;        /* impossible */
  451. X
  452. X        crm = &levl[xx][yy];
  453. X        if(!(crm->typ)) {
  454. X        if(rn2(100)) {
  455. X            crm->typ = CORR;
  456. X            crm->scrsym = CORR_SYM;
  457. X            if(nxcor && !rn2(50))
  458. X                (void) mksobj_at(BOULDER, xx, yy);
  459. X        } else {
  460. X            crm->typ = SCORR;
  461. X            crm->scrsym = ' ';    /* _not_ STONE_SYM */
  462. X        }
  463. X        } else
  464. X        if(crm->typ != CORR && crm->typ != SCORR) {
  465. X        /* strange ... */
  466. X        return;
  467. X        }
  468. X
  469. X        /* find next corridor position */
  470. X        dix = abs(xx-tx);
  471. X        diy = abs(yy-ty);
  472. X
  473. X        /* do we have to change direction ? */
  474. X        if(dy && dix > diy) {
  475. X        register int ddx = (xx > tx) ? -1 : 1;
  476. X
  477. X        crm = &levl[xx+ddx][yy];
  478. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
  479. X            dx = ddx;
  480. X            dy = 0;
  481. X            continue;
  482. X        }
  483. X        } else if(dx && diy > dix) {
  484. X        register int ddy = (yy > ty) ? -1 : 1;
  485. X
  486. X        crm = &levl[xx][yy+ddy];
  487. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
  488. X            dy = ddy;
  489. X            dx = 0;
  490. X            continue;
  491. X        }
  492. X        }
  493. X
  494. X        /* continue straight on? */
  495. X        crm = &levl[xx+dx][yy+dy];
  496. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  497. X        continue;
  498. X
  499. X        /* no, what must we do now?? */
  500. X        if(dx) {
  501. X        dx = 0;
  502. X        dy = (ty < yy) ? -1 : 1;
  503. X        crm = &levl[xx+dx][yy+dy];
  504. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  505. X            continue;
  506. X        dy = -dy;
  507. X        continue;
  508. X        } else {
  509. X        dy = 0;
  510. X        dx = (tx < xx) ? -1 : 1;
  511. X        crm = &levl[xx+dx][yy+dy];
  512. X        if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
  513. X            continue;
  514. X        dx = -dx;
  515. X        continue;
  516. X        }
  517. X    }
  518. X
  519. X    /* we succeeded in digging the corridor */
  520. X    dodoor(tt.x, tt.y, troom);
  521. X
  522. X    if(smeq[a] < smeq[b])
  523. X        smeq[b] = smeq[a];
  524. X    else
  525. X        smeq[a] = smeq[b];
  526. X}
  527. X
  528. Xstatic void
  529. Xmakecorridors() {
  530. X    register int a, b;
  531. X
  532. X    nxcor = 0;
  533. X    for(a = 0; a < nroom-1; a++)
  534. X        join(a, a+1);
  535. X    for(a = 0; a < nroom-2; a++)
  536. X        if(smeq[a] != smeq[a+2])
  537. X        join(a, a+2);
  538. X    for(a = 0; a < nroom; a++)
  539. X        for(b = 0; b < nroom; b++)
  540. X        if(smeq[a] != smeq[b])
  541. X            join(a, b);
  542. X    if(nroom > 2)
  543. X        for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
  544. X        a = rn2(nroom);
  545. X        b = rn2(nroom-2);
  546. X        if(b >= a) b += 2;
  547. X        join(a, b);
  548. X        }
  549. X}
  550. X
  551. Xstatic void
  552. Xdosdoor(x,y,aroom,type)
  553. Xregister int x, y;
  554. Xregister struct mkroom *aroom;
  555. Xregister int type;
  556. X{
  557. X    register struct mkroom *broom;
  558. X    register int tmp;
  559. X    boolean shdoor = in_shop(x, y);
  560. X
  561. X    if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */
  562. X        type = DOOR;
  563. X    levl[x][y].typ = type;
  564. X    if(type == DOOR) {
  565. X        if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */
  566. X        if(!rn2(5))
  567. X            levl[x][y].doormask = D_ISOPEN;
  568. X        else if(!rn2(6))
  569. X            levl[x][y].doormask = D_LOCKED;
  570. X        else
  571. X            levl[x][y].doormask = D_CLOSED;
  572. X
  573. X        if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25))
  574. X            levl[x][y].doormask |= D_TRAPPED;
  575. X        } else
  576. X#ifdef STUPID
  577. X        if (shdoor)
  578. X            levl[x][y].doormask = D_ISOPEN;
  579. X        else
  580. X            levl[x][y].doormask = D_NODOOR;
  581. X#else
  582. X        levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
  583. X#endif
  584. X        levl[x][y].scrsym = news0(x,y);
  585. X    } else { /* SDOOR */
  586. X        if(shdoor || !rn2(5))    levl[x][y].doormask = D_LOCKED;
  587. X        else            levl[x][y].doormask = D_CLOSED;
  588. X
  589. X        if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED;
  590. X    }
  591. X    aroom->doorct++;
  592. X    broom = aroom+1;
  593. X    if(broom->hx < 0) tmp = doorindex; else
  594. X    for(tmp = doorindex; tmp > broom->fdoor; tmp--)
  595. X        doors[tmp] = doors[tmp-1];
  596. X    doorindex++;
  597. X    doors[tmp].x = x;
  598. X    doors[tmp].y = y;
  599. X    for( ; broom->hx >= 0; broom++) broom->fdoor++;
  600. X}
  601. X
  602. Xstatic boolean
  603. Xplace_niche(aroom,dy,xx,yy)
  604. Xregister struct mkroom *aroom;
  605. Xint *dy, *xx, *yy;
  606. X{
  607. X    coord dd;
  608. X
  609. X    if(rn2(2)) {
  610. X        *dy = 1;
  611. X        finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
  612. X    } else {
  613. X        *dy = -1;
  614. X        finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
  615. X    }
  616. X    *xx = dd.x;
  617. X    *yy = dd.y;
  618. X    return(levl[*xx][(*yy)+(*dy)].typ == STONE);
  619. X}
  620. X
  621. X#ifdef ORACLE
  622. Xboolean
  623. Xplace_oracle(aroom,dy,xx,yy)
  624. Xregister struct mkroom *aroom;
  625. Xint *dy, *xx, *yy;
  626. X{
  627. X    if(!place_niche(aroom,dy,xx,yy)) return FALSE;
  628. X
  629. X    dosdoor(*xx,*yy,aroom,DOOR);
  630. X    levl[*xx][*yy].doormask = D_NODOOR;
  631. X    return TRUE;
  632. X}
  633. X#endif
  634. X
  635. X/* there should be one of these per trap */
  636. Xconst char *engravings[] = {    "", "", "", "", "", "",
  637. X                "?la? ?as ?er?", "ad ae?ar um",
  638. X                "", "", "", "" ,""
  639. X                , "", "ad ae?ar um"
  640. X#ifdef SPELLS
  641. X                ,""
  642. X#endif
  643. X                ,""
  644. X#ifdef POLYSELF
  645. X                ,""
  646. X#endif
  647. X                ,""
  648. X                };
  649. X
  650. Xstatic void
  651. Xmakeniche(trap_type)
  652. Xint trap_type;
  653. X{
  654. X    register struct mkroom *aroom;
  655. X    register struct rm *rm;
  656. X    register int vct = 8;
  657. X    int dy, xx, yy;
  658. X    register struct trap *ttmp;
  659. X
  660. X    if(doorindex < DOORMAX)
  661. X      while(vct--) {
  662. X        aroom = &rooms[rn2(nroom)];
  663. X        if(aroom->rtype != OROOM) continue;    /* not an ordinary room */
  664. X        if(aroom->doorct == 1 && rn2(5)) continue;
  665. X        if(!place_niche(aroom,&dy,&xx,&yy)) continue;
  666. X
  667. X        rm = &levl[xx][yy+dy];
  668. X        if(trap_type || !rn2(4)) {
  669. X
  670. X        rm->typ = SCORR;
  671. X        rm->scrsym = ' ';        /* _not_ STONE_SYM */
  672. X        if(trap_type) {
  673. X            ttmp = maketrap(xx, yy+dy, trap_type);
  674. X            ttmp->once = 1;
  675. X            if (strlen(engravings[trap_type]) > 0)
  676. X            make_engr_at(xx, yy-dy, engravings[trap_type]);
  677. X        }
  678. X        dosdoor(xx, yy, aroom, SDOOR);
  679. X        } else {
  680. X        rm->typ = CORR;
  681. X        rm->scrsym = CORR_SYM;
  682. X        if(rn2(7))
  683. X            dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
  684. X        else {
  685. X            (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
  686. X            if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE);
  687. X        }
  688. X        }
  689. X        return;
  690. X    }
  691. X}
  692. X
  693. Xstatic void
  694. Xmake_niches()
  695. X{
  696. X    register int ct = rnd((nroom>>1) + 1);
  697. X    boolean    ltptr = TRUE,
  698. X        vamp = TRUE;
  699. X
  700. X    while(ct--) {
  701. X
  702. X        if(dlevel > 15 && !rn2(6) && ltptr) {
  703. X
  704. X            ltptr = FALSE;
  705. X            makeniche(LEVEL_TELEP);
  706. X        } else if (dlevel > 5 && dlevel < 25
  707. X               && !rn2(6) && vamp) {
  708. X
  709. X            vamp = FALSE;
  710. X            makeniche(TRAPDOOR);
  711. X        } else    makeniche(NO_TRAP);
  712. X    }
  713. X}
  714. X
  715. Xstatic void
  716. Xmakebigroom()
  717. X{
  718. X    register int x,y,n;
  719. X    register struct mkroom *croom;
  720. X    register struct monst *tmonst;
  721. X
  722. X    /* make biggest possible room; make sure it's lit */
  723. X    (void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE);
  724. X    croom = &rooms[0];
  725. X
  726. X    /* add extra monsters and goodies */
  727. X    n = 10 + rn2(15);
  728. X    while (n--) {
  729. X        x = somex(croom);
  730. X        y = somey(croom);
  731. X        tmonst = makemon((struct permonst *) 0,x,y);
  732. X        if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER])
  733. X            (void) maketrap(x,y,WEB);
  734. X        if (tmonst && rn2(2))
  735. X            tmonst->msleep = 1;
  736. X    }
  737. X    n = 6 + rn2(10);
  738. X    while (n--)
  739. X        (void) mkobj_at(0,somex(croom),somey(croom),TRUE);
  740. X}
  741. X
  742. Xstatic void
  743. Xmakevtele()
  744. X{
  745. X    makeniche(TELEP_TRAP);
  746. X}
  747. X
  748. X#define rntwixt(L1,L2)    rn1((L2)-(L1),L1)
  749. X
  750. Xstatic void
  751. Xinit_levels()
  752. X{
  753. X#if defined(STRONGHOLD) && defined(MUSIC)
  754. X    register int x;
  755. X#endif
  756. X
  757. X#ifdef LINT    /* handle constant in conditional context */
  758. X    medusa_level = 0;
  759. X#else
  760. X    medusa_level = rn1(3, HELLLEVEL - 5);
  761. X#endif /* LINT */
  762. X#ifdef STRONGHOLD
  763. X    stronghold_level = rn1(5, medusa_level)+1;
  764. X# ifdef MUSIC
  765. X    for (x=0; x<5; x++)
  766. X        tune[x] = 'A' + rn2(7);
  767. X    tune[5] = 0;
  768. X# endif
  769. X    /* The tower will be on 3 levels */
  770. X    tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1;
  771. X    /* We don't want the wizard in Vlad's tower */
  772. X    do
  773. X        wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1;
  774. X    while (wiz_level >= tower_level && wiz_level <= tower_level + 2);
  775. X#else
  776. X    wiz_level     = rntwixt(medusa_level, MAXLEVEL)+1;
  777. X#endif /* STRONGHOLD /**/
  778. X#ifdef WIZARD
  779. X    if (!rn2(15) || wizard)
  780. X#else
  781. X    if (!rn2(15))
  782. X#endif
  783. X        /* between the middle of the dungeon and the medusa level */
  784. X        bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level);
  785. X#ifdef REINCARNATION
  786. X# ifdef WIZARD
  787. X    if (!rn2(3) || wizard)
  788. X# else
  789. X    if (!rn2(3))
  790. X# endif
  791. X        rogue_level = rn1(5,10);
  792. X#endif
  793. X#ifdef ORACLE
  794. X    oracle_level = rn1(4,5);
  795. X#endif
  796. X}
  797. X
  798. X#undef rntwixt
  799. X
  800. Xstatic void
  801. Xmakelevel() {
  802. X    register struct mkroom *croom, *troom;
  803. X    register unsigned int tryct;
  804. X    register int x,y;
  805. X    struct monst *tmonst;    /* always put a web with a spider */
  806. X
  807. X    nroom = 0;
  808. X    doorindex = 0;
  809. X    rooms[0].hx = -1;    /* in case we are in a maze */
  810. X
  811. X    for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
  812. X        levl[x][y] = zerorm;
  813. X        level.objects[x][y] = (struct obj *)0;
  814. X        level.monsters[x][y] = (struct monst *)0;
  815. X    }
  816. X
  817. X    oinit();    /* assign level dependent obj probabilities */
  818. X    fountsound = 0;
  819. X    sinksound = 0;
  820. X
  821. X    if (wiz_level == 0)
  822. X        init_levels();
  823. X    if (
  824. X#ifndef STRONGHOLD
  825. X        Inhell
  826. X#else
  827. X        dlevel >= stronghold_level || dlevel < 0
  828. X#endif
  829. X        || (dlevel > medusa_level && rn2(5))
  830. X       ) {
  831. X        makemaz();
  832. X        return;
  833. X    }
  834. X
  835. X    /* construct the rooms */
  836. X    nroom = 0;
  837. X    secret = FALSE;
  838. X
  839. X#ifdef REINCARNATION
  840. X    if (dlevel == rogue_level) {
  841. X        makeroguerooms();
  842. X        makerogueghost();
  843. X    } else
  844. X#endif
  845. X    if (dlevel == bigroom_level)
  846. X        makebigroom();
  847. X    else
  848. X        (void) makerooms();
  849. X
  850. X    /* construct stairs (up and down in different rooms if possible) */
  851. X    croom = &rooms[rn2(nroom)];
  852. X    xdnstair = somex(croom);
  853. X    ydnstair = somey(croom);
  854. X    levl[xdnstair][ydnstair].scrsym = DN_SYM;
  855. X    levl[xdnstair][ydnstair].typ = STAIRS;
  856. X#ifdef MEDUSA
  857. X    if (dlevel == medusa_level) {
  858. X        struct monst *mtmp;
  859. X        struct obj *otmp;
  860. X
  861. X        if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair))
  862. X            mtmp->msleep = 1;
  863. X        for (tryct = rn1(1,3); tryct; tryct--) {
  864. X            x = somex(croom); y = somey(croom);
  865. X            if (goodpos(x,y,(struct permonst *)0)) {
  866. X                otmp = mk_tt_object(STATUE, x, y);
  867. X                while(otmp &&
  868. X                      resists_ston(&mons[otmp->corpsenm])) {
  869. X                    otmp->corpsenm = rndmonnum();
  870. X                    otmp->owt = weight(otmp);
  871. X                }
  872. X            }
  873. X        }
  874. X    }
  875. X#endif
  876. X    if(nroom > 1) {
  877. X        troom = croom;
  878. X        croom = &rooms[rn2(nroom-1)];
  879. X        if(croom >= troom) croom++;
  880. X    }
  881. X    do {
  882. X        xupstair = somex(croom);
  883. X        yupstair = somey(croom);
  884. X    } while(occupied(xupstair, yupstair));
  885. X    levl[xupstair][yupstair].scrsym = UP_SYM;
  886. X    levl[xupstair][yupstair].typ = STAIRS;
  887. X#ifdef STRONGHOLD
  888. X    xdnladder = ydnladder = xupladder = yupladder = 0;
  889. X#endif
  890. X    is_maze_lev = FALSE;
  891. X
  892. X#if defined(SYSV) || defined(DGUX)
  893. X    qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp);
  894. X#else
  895. X    qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp);
  896. X#endif
  897. X#ifdef REINCARNATION
  898. X    if (dlevel == rogue_level) {
  899. X       You("feel as though you were here in a previous lifetime.");
  900. X       goto skip0;
  901. X    }
  902. X#endif
  903. X    makecorridors();
  904. X    make_niches();
  905. X
  906. X    /* make a secret treasure vault, not connected to the rest */
  907. X    if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) {
  908. X
  909. X        troom = &rooms[nroom];
  910. X        secret = TRUE;
  911. X        if(makerooms()) {
  912. X            troom->rtype = VAULT;        /* treasure vault */
  913. X            for(x = troom->lx; x <= troom->hx; x++)
  914. X            for(y = troom->ly; y <= troom->hy; y++)
  915. X                mkgold((long)(rnd(dlevel*100) + 50), x, y);
  916. X            if(!rn2(3))
  917. X                makevtele();
  918. X        }
  919. X    }
  920. X
  921. X#ifdef WIZARD
  922. X    if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else
  923. X#endif
  924. X#ifdef ORACLE
  925. X    if(dlevel == oracle_level) mkroom(DELPHI);
  926. X    /*  It is possible that we find no good place to set up Delphi.
  927. X     *  It is also possible to get more than one Delphi using bones levels.
  928. X     *  The first is not a problem; the second is a minor nuisance.
  929. X     */
  930. X    else
  931. X#endif
  932. X    if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE);
  933. X    else
  934. X#ifdef THRONES
  935. X    if(dlevel > 4 && !rn2(6)) mkroom(COURT);
  936. X    else
  937. X#endif
  938. X    if(dlevel > 6 && !rn2(7)) mkroom(ZOO);
  939. X    else
  940. X#ifdef ALTARS
  941. X    if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE);
  942. X    else
  943. X#endif
  944. X    if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD))
  945. X        mkroom(BEEHIVE);
  946. X    else
  947. X    if(dlevel > 11 && !rn2(6)) mkroom(MORGUE);
  948. X    else
  949. X#ifdef ARMY
  950. X    if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD))
  951. X        mkroom(BARRACKS);
  952. X    else
  953. X#endif
  954. X    if(dlevel > 18 && !rn2(6)) mkroom(SWAMP);
  955. X
  956. X#ifdef REINCARNATION
  957. Xskip0:
  958. X#endif
  959. X    /* for each room: put things inside */
  960. X    for(croom = rooms; croom->hx > 0; croom++) {
  961. X        register boolean boxinlev = FALSE;
  962. X
  963. X        if(croom->rtype != OROOM) continue;
  964. X
  965. X        /* put a sleeping monster inside */
  966. X        /* Note: monster may be on the stairs. This cannot be
  967. X           avoided: maybe the player fell through a trap door
  968. X           while a monster was on the stairs. Conclusion:
  969. X           we have to check for monsters on the stairs anyway. */
  970. X
  971. X        if(u.uhave_amulet || !rn2(3)) {
  972. X            x = somex(croom); y = somey(croom);
  973. X            tmonst = makemon((struct permonst *) 0, x,y);
  974. X            if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER])
  975. X            (void) maketrap (x,y,WEB);
  976. X        }
  977. X        /* put traps and mimics inside */
  978. X        goldseen = FALSE;
  979. X        while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
  980. X        if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom));
  981. X#ifdef REINCARNATION
  982. X        if (dlevel == rogue_level) goto skip_nonrogue;
  983. X#endif
  984. X#ifdef FOUNTAINS
  985. X        if(!rn2(10)) mkfount(0,croom);
  986. X#endif
  987. X#ifdef SINKS
  988. X        if(!rn2(60)) mksink(croom);
  989. X#endif
  990. X#ifdef ALTARS
  991. X        if(!rn2(60)) mkaltar(croom);
  992. X#endif
  993. X        /* put statues inside */
  994. X#ifdef MEDUSA
  995. X        if(!rn2(dlevel == medusa_level ? 1 : 20)) {
  996. X            struct obj *otmp;
  997. X
  998. X            if (!rn2(dlevel == medusa_level ? 2 : 50))
  999. X                otmp = mk_tt_object(STATUE,
  1000. X                        somex(croom), somey(croom));
  1001. X            else {
  1002. X                otmp = mkcorpstat(STATUE, (struct permonst *)0,
  1003. X                        somex(croom), somey(croom));
  1004. X            }
  1005. X            if (dlevel == medusa_level && otmp) {
  1006. X                /* Medusa statues don't contain books */
  1007. X                otmp->spe = 0;
  1008. X                while(resists_ston(&mons[otmp->corpsenm])) {
  1009. X                    otmp->corpsenm = rndmonnum();
  1010. X                    otmp->owt = weight(otmp);
  1011. X                }
  1012. X            }
  1013. X        }
  1014. X#else
  1015. X        if(!rn2(20))
  1016. X                (void) mkcorpstat(STATUE, (struct permonst *)0,
  1017. X                        somex(croom), somey(croom));
  1018. X#endif
  1019. X
  1020. X        /* put box/chest inside */
  1021. X        if(!rn2(20) && !boxinlev) {
  1022. X
  1023. X            boxinlev = TRUE;
  1024. X            (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
  1025. X                     somex(croom), somey(croom));
  1026. X        }
  1027. X
  1028. X#ifdef REINCARNATION
  1029. X    skip_nonrogue:
  1030. X#endif
  1031. X        if(!rn2(3)) {
  1032. X            (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
  1033. X            tryct = 0;
  1034. X            while(!rn2(5)) {
  1035. X                if(++tryct > 100){
  1036. X                    Printf("tryct overflow4\n");
  1037. X                    break;
  1038. X                }
  1039. X                (void) mkobj_at(0, somex(croom), somey(croom),
  1040. X                                    TRUE);
  1041. X            }
  1042. X        }
  1043. X    }
  1044. X}
  1045. X
  1046. Xvoid
  1047. Xmklev()
  1048. X{
  1049. X    if(getbones()) return;
  1050. X
  1051. X    in_mklev = TRUE;
  1052. X    makelevel();
  1053. X    bound_digging();
  1054. X    in_mklev = FALSE;
  1055. X}
  1056. X
  1057. Xstatic boolean
  1058. Xbydoor(x, y)
  1059. Xregister xchar x, y;
  1060. X{
  1061. X    register boolean tmp1, tmp2;
  1062. X
  1063. X    /* break up large expression to help some compilers */
  1064. X    tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||
  1065. X        IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR);
  1066. X    tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR ||
  1067. X        IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR);
  1068. X    return(tmp1 || tmp2);
  1069. X}
  1070. X
  1071. X/* see whether it is allowable to create a door at [x,y] */
  1072. Xint
  1073. Xokdoor(x,y)
  1074. Xregister xchar x, y;
  1075. X{
  1076. X    register boolean near_door = bydoor(x, y);
  1077. X
  1078. X    return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
  1079. X               doorindex < DOORMAX && !near_door);
  1080. X}
  1081. X
  1082. Xvoid
  1083. Xdodoor(x,y,aroom)
  1084. Xregister int x, y;
  1085. Xregister struct mkroom *aroom;
  1086. X{
  1087. X    if(doorindex >= DOORMAX) {
  1088. X        impossible("DOORMAX exceeded?");
  1089. X        return;
  1090. X    }
  1091. X    if(!okdoor(x,y) && nxcor)
  1092. X        return;
  1093. X    dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
  1094. X}
  1095. X
  1096. Xstatic boolean
  1097. Xoccupied(x, y)
  1098. Xregister xchar x, y;
  1099. X{
  1100. X    return(t_at(x, y) || levl[x][y].typ == STAIRS
  1101. X#ifdef FOUNTAINS
  1102. X        || IS_FOUNTAIN(levl[x][y].typ)
  1103. X#endif
  1104. X#ifdef THRONES
  1105. X        || IS_THRONE(levl[x][y].typ)
  1106. X#endif
  1107. X#ifdef SINKS
  1108. X        || IS_SINK(levl[x][y].typ)
  1109. X#endif
  1110. X#ifdef ALTARS
  1111. X        || levl[x][y].typ == ALTAR
  1112. X#endif
  1113. X        || is_pool(x,y)
  1114. X        );
  1115. X}
  1116. X
  1117. X/* make a trap somewhere (in croom if mazeflag = 0) */
  1118. Xvoid
  1119. Xmktrap(num, mazeflag, croom)
  1120. Xregister int num, mazeflag;
  1121. Xregister struct mkroom *croom;
  1122. X{
  1123. X    register struct trap *ttmp;
  1124. X    register int kind,nomonst,nomimic,nospider,
  1125. X#ifdef POLYSELF
  1126. X            nopoly,
  1127. X#endif
  1128. X            nospikes, nolevltp,
  1129. X            nolandmine,
  1130. X            tryct = 0;
  1131. X
  1132. X    xchar mx,my;
  1133. X
  1134. X#ifdef __GNULINT__
  1135. X    kind = nomimic = 0;
  1136. X#endif
  1137. X    if(!num || num >= TRAPNUM) {
  1138. X        nomonst = (dlevel < 4) ? 1 : 0;
  1139. X        nolevltp = (dlevel < 5) ? 1 : 0;
  1140. X        nospikes = (dlevel < 6) ? 1 : 0;
  1141. X        nospider = (dlevel < 7) ? 1 : 0;
  1142. X#ifdef POLYSELF
  1143. X        nopoly = (dlevel < 6) ? 1 : 0;
  1144. X#endif
  1145. X        nolandmine = (dlevel < 5) ? 1 : 0;
  1146. X        nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
  1147. X        if((mons[PM_SMALL_MIMIC].geno & G_GENOD) &&
  1148. X           (mons[PM_LARGE_MIMIC].geno & G_GENOD) &&
  1149. X           (mons[PM_GIANT_MIMIC].geno & G_GENOD))
  1150. X            nomimic = 1;
  1151. X        if(mons[PM_GIANT_SPIDER].geno & G_GENOD)
  1152. X            nospider = 1;
  1153. X
  1154. X        do {
  1155. X#ifdef REINCARNATION
  1156. X            if (dlevel==rogue_level) {
  1157. X            switch(rn2(7)) {
  1158. X                 case 0: kind = BEAR_TRAP; break;
  1159. X                 case 1: kind = ARROW_TRAP; break;
  1160. X                 case 2: kind = DART_TRAP; break;
  1161. X                 case 3: kind = TRAPDOOR; break;
  1162. X                 case 4: kind = PIT; break;
  1163. X                 case 5: kind = SLP_GAS_TRAP; break;
  1164. X                 case 6: kind = RUST_TRAP; break;
  1165. X            }
  1166. X            } else
  1167. X#endif
  1168. X                kind = rnd(TRAPNUM-1);
  1169. X            if((kind == MONST_TRAP && (nomonst && nomimic))
  1170. X            || ((kind == WEB) && nospider)
  1171. X            || (kind == SPIKED_PIT && nospikes)
  1172. X            || (kind == LEVEL_TELEP && nolevltp)
  1173. X#ifdef POLYSELF
  1174. X            || (kind == POLY_TRAP && nopoly)
  1175. X#endif
  1176. X            || (kind == LANDMINE && nolandmine)
  1177. X            )  kind = NO_TRAP;
  1178. X        } while(kind == NO_TRAP);
  1179. X    } else kind = num;
  1180. X
  1181. X    if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) {
  1182. X        register struct monst *mtmp;
  1183. X
  1184. X        do {
  1185. X            if(++tryct > 200) return;
  1186. X            /* note: fakedoor maybe on actual door */
  1187. X            if(rn2(2)){
  1188. X                if(rn2(2))    mx = croom->hx+1;
  1189. X                else    mx = croom->lx-1;
  1190. X                my = somey(croom);
  1191. X            } else {
  1192. X                if(rn2(2))    my = croom->hy+1;
  1193. X                else    my = croom->ly-1;
  1194. X                mx = somex(croom);
  1195. X            }
  1196. X        } while
  1197. X            (MON_AT(mx, my));
  1198. X
  1199. X        if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) {
  1200. X            mtmp->mimic = 1;
  1201. X            mtmp->m_ap_type = M_AP_FURNITURE;
  1202. X            mtmp->mappearance = S_cdoor;
  1203. X        }
  1204. X        return;
  1205. X    }
  1206. X
  1207. X    do {
  1208. X        if(++tryct > 200)
  1209. X            return;
  1210. X        if(mazeflag){
  1211. X            coord mm;
  1212. X            mazexy(&mm);
  1213. X            mx = mm.x;
  1214. X            my = mm.y;
  1215. X        } else {
  1216. X            mx = somex(croom);
  1217. X            my = somey(croom);
  1218. X        }
  1219. X    } while(occupied(mx, my));
  1220. X
  1221. X    ttmp = maketrap(mx, my, kind);
  1222. X    if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my);
  1223. X    if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP)
  1224. X        ttmp->tseen = 1;
  1225. X}
  1226. X
  1227. X#ifdef FOUNTAINS
  1228. Xvoid
  1229. Xmkfount(mazeflag,croom)
  1230. Xregister struct mkroom *croom;
  1231. Xregister int mazeflag;
  1232. X{
  1233. X    register xchar mx,my;
  1234. X    register int tryct = 0;
  1235. X
  1236. X    do {
  1237. X        if(++tryct > 200) return;
  1238. X        if(mazeflag) {
  1239. X         coord mm;
  1240. X         mazexy(&mm);
  1241. X         mx = mm.x;
  1242. X         my = mm.y;
  1243. X        } else {
  1244. X         mx = somex(croom);
  1245. X         my = somey(croom);
  1246. X        }
  1247. X    } while(occupied(mx, my) || bydoor(mx, my));
  1248. X
  1249. X    /* Put a fountain at mx, my */
  1250. X    levl[mx][my].typ = FOUNTAIN;
  1251. X    levl[mx][my].scrsym = FOUNTAIN_SYM;
  1252. X
  1253. X    fountsound++;
  1254. X}
  1255. X#endif /* FOUNTAINS /**/
  1256. X
  1257. X#ifdef SINKS
  1258. Xstatic void
  1259. Xmksink(croom)
  1260. Xregister struct mkroom *croom;
  1261. X{
  1262. X    register xchar mx,my;
  1263. X    register int tryct = 0;
  1264. X
  1265. X    do {
  1266. X        if(++tryct > 200) return;
  1267. X        mx = somex(croom);
  1268. X        my = somey(croom);
  1269. X    } while(occupied(mx, my) || bydoor(mx, my));
  1270. X
  1271. X    /* Put a sink at mx, my */
  1272. X    levl[mx][my].typ = SINK;
  1273. X    levl[mx][my].scrsym = SINK_SYM;
  1274. X
  1275. X    sinksound++;
  1276. X}
  1277. X#endif /* SINKS /**/
  1278. X
  1279. X
  1280. X#ifdef ALTARS
  1281. Xstatic void
  1282. Xmkaltar(croom)
  1283. Xregister struct mkroom *croom;
  1284. X{
  1285. X    register xchar mx,my;
  1286. X    register int tryct = 0;
  1287. X
  1288. X    if(croom->rtype != OROOM) return;
  1289. X
  1290. X    do {
  1291. X        if(++tryct > 200) return;
  1292. X        mx = somex(croom);
  1293. X        my = somey(croom);
  1294. X    } while(occupied(mx, my) || bydoor(mx, my));
  1295. X
  1296. X    /* Put an altar at mx, my */
  1297. X    levl[mx][my].typ = ALTAR;
  1298. X    levl[mx][my].scrsym = ALTAR_SYM;
  1299. X    /* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */
  1300. X    levl[mx][my].altarmask = rn2((int)A_LAW+1);
  1301. X}
  1302. X#endif /* ALTARS /**/
  1303. END_OF_FILE
  1304. if test 28964 -ne `wc -c <'src/mklev.c'`; then
  1305.     echo shar: \"'src/mklev.c'\" unpacked with wrong size!
  1306. fi
  1307. # end of 'src/mklev.c'
  1308. fi
  1309. if test -f 'src/monmove.c' -a "${1}" != "-c" ; then 
  1310.   echo shar: Will not clobber existing file \"'src/monmove.c'\"
  1311. else
  1312. echo shar: Extracting \"'src/monmove.c'\" \(24074 characters\)
  1313. sed "s/^X//" >'src/monmove.c' <<'END_OF_FILE'
  1314. X/*    SCCS Id: @(#)monmove.c    3.0    89/11/21
  1315. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1316. X/* NetHack may be freely redistributed.  See license for details. */
  1317. X
  1318. X#ifndef LINT    /* comment line for pre-compiled headers */
  1319. X# ifndef __STDC__    /* comment line for pre-compiled headers */
  1320. X#define TRAP_H    /* comment line for pre-compiled headers */
  1321. X/* block some unused #defines to avoid overloading some cpp's */
  1322. X# endif    /* comment line for pre-compiled headers */
  1323. X#endif    /* comment line for pre-compiled headers */
  1324. X
  1325. X#include "hack.h"
  1326. X#include "mfndpos.h"
  1327. X#ifdef NAMED_ITEMS
  1328. X#  include "artifact.h"
  1329. X#endif
  1330. X
  1331. X#ifdef OVL1
  1332. Xstatic void FDECL(distfleeck,(struct monst *,int *,int *,int *));
  1333. X#endif /* OVL1 */
  1334. X
  1335. X#ifdef OVL0
  1336. X# ifdef POLYSELF
  1337. Xstatic boolean FDECL(itsstuck,(struct monst *));
  1338. X# endif
  1339. X#endif /* OVL0 */
  1340. X
  1341. X#ifdef OVLB
  1342. X
  1343. Xboolean /* TRUE : mtmp died */
  1344. Xmb_trapped(mtmp)
  1345. Xregister struct monst *mtmp;
  1346. X{
  1347. X    if (flags.verbose) {
  1348. X        if (cansee(mtmp->mx, mtmp->my))
  1349. X           pline("KABOOM!!  You see a door explode.");
  1350. X        else if (flags.soundok)
  1351. X               You("hear a distant explosion.");
  1352. X    }
  1353. X    mtmp->mstun = 1;
  1354. X    mtmp->mhp -= rnd(15);
  1355. X    if(mtmp->mhp <= 0) {
  1356. X        mondied(mtmp);
  1357. X        return(TRUE);
  1358. X    }
  1359. X    return(FALSE);
  1360. X}
  1361. X
  1362. Xboolean  
  1363. Xmdig_tunnel(mtmp)  /* FALSE: monster died */
  1364. Xregister struct monst *mtmp;
  1365. X{
  1366. X    register struct rm *here;
  1367. X    register int pile = rnd(12);
  1368. X    boolean canseeit = cansee(mtmp->mx, mtmp->my);
  1369. X    here = &levl[mtmp->mx][mtmp->my];
  1370. X
  1371. X    if (here->typ == SDOOR)
  1372. X        here->typ = DOOR;
  1373. X    if(IS_ROCK(here->typ)) {
  1374. X        /* Just ate something. */
  1375. X        if(IS_WALL(here->typ)) {
  1376. X        if (!(here->diggable & W_NONDIGGABLE)) {
  1377. X            if(flags.soundok && flags.verbose && !rn2(5))
  1378. X                       You("hear the sound of crashing rock.");
  1379. X            if(!is_maze_lev) {
  1380. X                  here->typ = DOOR;
  1381. X                  here->doormask = D_NODOOR;
  1382. X            }
  1383. X            else
  1384. X                  here->typ = ROOM;
  1385. X        }
  1386. X        } else    
  1387. X            here->typ = CORR;
  1388. X        mnewsym(mtmp->mx, mtmp->my);
  1389. X    } else         /* Eats away door if present & closed or locked */
  1390. X        if(closed_door(mtmp->mx, mtmp->my)) {
  1391. X            if(here->doormask & D_TRAPPED) {
  1392. X                    here->doormask = D_NODOOR;
  1393. X                    if(mb_trapped(mtmp)) return(FALSE);
  1394. X            } else {
  1395. X                    if(!rn2(3) && flags.verbose)
  1396. X                    /* not too often.. */
  1397. X                        You("feel an unexpected draft of air.");
  1398. X                    here->doormask = D_BROKEN;
  1399. X            }
  1400. X                mnewsym(mtmp->mx, mtmp->my);
  1401. X            } else 
  1402. X            /* it doesn't leave rocks if it didn't dig */
  1403. X            return TRUE; 
  1404. X
  1405. X    /* Left behind a pile? */
  1406. X    if(pile < 5) {
  1407. X        if(pile == 1)
  1408. X        (void) mksobj_at(BOULDER, mtmp->mx, mtmp->my);
  1409. X        else
  1410. X        (void) mksobj_at(ROCK, mtmp->mx, mtmp->my);
  1411. X    }
  1412. X    here->seen = TRUE; /* required for newsym and mnewsym to work */
  1413. X    if(canseeit && mtmp->minvis && !See_invisible)
  1414. X        newsym(mtmp->mx,mtmp->my);
  1415. X    else
  1416. X        mnewsym(mtmp->mx,mtmp->my);
  1417. X    if (!canseeit)
  1418. X        here->seen = FALSE;
  1419. X    return(TRUE);
  1420. X}
  1421. X
  1422. X#endif /* OVLB */
  1423. X#ifdef OVL1
  1424. X
  1425. Xint
  1426. Xdochugw(mtmp)
  1427. X    register struct monst *mtmp;
  1428. X{
  1429. X    register int x = mtmp->mx;
  1430. X    register int y = mtmp->my;
  1431. X    register int rd = dochug(mtmp);
  1432. X    register int dd;
  1433. X
  1434. X    if(!rd && !mtmp->mpeaceful &&
  1435. X            (dd = dist(mtmp->mx,mtmp->my)) < dist(x,y) &&
  1436. X            dd < 100 && !canseemon(mtmp)) {
  1437. X#ifdef NAMED_ITEMS
  1438. X        /* Note: this assumes we only want to warn against the monster which
  1439. X         * the weapon does extra damage to, as there is no "monster which
  1440. X         * the weapon warns against" field.
  1441. X         */
  1442. X        if(spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp->data,1))
  1443. X            warnlevel = 100;
  1444. X        else
  1445. X#endif
  1446. X        if (Warning && mtmp->m_lev > warnlevel)
  1447. X            warnlevel = mtmp->m_lev;
  1448. X    }
  1449. X    return(rd);
  1450. X}
  1451. X
  1452. X#endif /* OVL1 */
  1453. X#ifdef OVL2
  1454. X
  1455. Xboolean
  1456. Xonscary(x, y, mtmp)
  1457. Xint x, y;
  1458. Xstruct monst *mtmp;
  1459. X{
  1460. X    /* Note: minotaurs must be immune to scare monster to avoid abuse
  1461. X     * from creating them and taking their wands, then polymorphing 60
  1462. X     * or so wands to get wishing...
  1463. X     */
  1464. X    if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee ||
  1465. X            mtmp->data->mlet == S_HUMAN || mtmp->mpeaceful ||
  1466. X            mtmp->data == &mons[PM_MINOTAUR])
  1467. X        return(FALSE);
  1468. X    return(
  1469. X#ifdef ELBERETH
  1470. X           sengr_at("Elbereth", x, y) ||
  1471. X#endif
  1472. X            sobj_at(SCR_SCARE_MONSTER, x, y) != (struct obj *)0);
  1473. X}
  1474. X
  1475. X#endif /* OVL2 */
  1476. X#ifdef OVL1
  1477. X
  1478. Xstatic void
  1479. Xdistfleeck(mtmp,inrange,nearby,scared)
  1480. Xregister struct monst *mtmp;
  1481. Xint *inrange, *nearby, *scared;
  1482. X{
  1483. X    int seescaryx, seescaryy;
  1484. X
  1485. X    *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
  1486. X                            (BOLT_LIM * BOLT_LIM));
  1487. X    *nearby = monnear(mtmp, mtmp->mux, mtmp->muy);
  1488. X
  1489. X    /* Note: if your image is displaced, the monster sees the Elbereth
  1490. X     * at your displaced position, thus never attacking your displaced
  1491. X     * position, but possibly attacking you by accident.  If you are
  1492. X     * invisible, it sees the Elbereth at your real position, thus never
  1493. X     * running into you by accident but possibly attacking the spot
  1494. X     * where it guesses you are.
  1495. X     */
  1496. X    if (Invis && !perceives(mtmp->data)) {
  1497. X        seescaryx = mtmp->mux;
  1498. X        seescaryy = mtmp->muy;
  1499. X    } else {
  1500. X        seescaryx = u.ux;
  1501. X        seescaryy = u.uy;
  1502. X    }
  1503. X    *scared = (*nearby && onscary(seescaryx, seescaryy, mtmp));
  1504. X
  1505. X    if(*scared && !mtmp->mflee) {
  1506. X#ifdef POLYSELF
  1507. X        if (!sticks(uasmon))
  1508. X#endif
  1509. X            unstuck(mtmp);    /* monster lets go when fleeing */
  1510. X        mtmp->mflee = 1;
  1511. X#ifdef STUPID
  1512. X        if (rn2(7))
  1513. X            mtmp->mfleetim = rnd(10);
  1514. X        else
  1515. X            mtmp->mfleetim = rnd(100);
  1516. X#else
  1517. X        mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
  1518. X#endif
  1519. X    }
  1520. X
  1521. X}
  1522. X
  1523. X/* returns 1 if monster died moving, 0 otherwise */
  1524. Xint
  1525. Xdochug(mtmp)
  1526. Xregister struct monst *mtmp;
  1527. X{
  1528. X    register struct permonst *mdat = mtmp->data;
  1529. X    register int tmp=0;
  1530. X    int inrange, nearby, scared;
  1531. X
  1532. X/*    Pre-movement adjustments    */
  1533. X
  1534. X    if(mtmp->cham && !rn2(6))    /* polymorph chameleons */
  1535. X        (void) newcham(mtmp, (struct permonst *)0);
  1536. X
  1537. X    /* regenerate monsters */
  1538. X    if((!(moves%20) || regenerates(mdat)) && mtmp->mhp < mtmp->mhpmax)
  1539. X        mtmp->mhp++;
  1540. X    if(mtmp->mspec_used) mtmp->mspec_used--;
  1541. X
  1542. X    /* polymorph lycanthropes */
  1543. X    were_change(mtmp);
  1544. X
  1545. X    if(!mtmp->mcanmove) {
  1546. X        if (Hallucination) pmon(mtmp);
  1547. X        return(0);    /* frozen monsters don't do anything */
  1548. X    }
  1549. X
  1550. X    if(mtmp->msleep)    /* there is a chance we will wake it */
  1551. X        if(!disturb(mtmp)) return(0);
  1552. X
  1553. X    /* not frozen or sleeping: wipe out texts written in the dust */
  1554. X    wipe_engr_at(mtmp->mx, mtmp->my, 1);
  1555. X
  1556. X    /* confused monsters get unconfused with small probability */
  1557. X    if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
  1558. X
  1559. X    /* stunned monsters get un-stunned with larger probability */
  1560. X    if(mtmp->mstun && !rn2(10)) mtmp->mstun = 0;
  1561. X
  1562. X    /* some monsters teleport */
  1563. X    if(mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz) {
  1564. X        rloc(mtmp);
  1565. X        return(0);
  1566. X    }
  1567. X    if(mdat->mmove < rnd(6)) return(0);
  1568. X
  1569. X    /* fleeing monsters might regain courage */
  1570. X    if(mtmp->mflee && !mtmp->mfleetim
  1571. X       && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0;
  1572. X
  1573. X    set_apparxy(mtmp);
  1574. X    /* Must be done after you move and before the monster does.  The
  1575. X     * set_apparxy() call in m_move() doesn't suffice since the variables
  1576. X     * inrange, etc... all depend on stuff set by set_apparxy().
  1577. X     */
  1578. X
  1579. X    /* The Wizard's prime directive */
  1580. X    /* may teleport, so do it before inrange is set */
  1581. X    if(mtmp->iswiz)
  1582. X        (void) wiz_get_amulet(mtmp);
  1583. X
  1584. X    /* check distance and scariness of attacks */
  1585. X    distfleeck(mtmp,&inrange,&nearby,&scared);
  1586. X
  1587. X#ifdef INFERNO        /* Demonic Blackmail! */
  1588. X    if(nearby && mdat->msound == MS_BRIBE &&
  1589. X       mtmp->mpeaceful && !mtmp->mtame) {
  1590. X        if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
  1591. X            pline("%s whispers something to thin air.",
  1592. X                cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
  1593. X# ifdef POLYSELF
  1594. X            if (is_demon(uasmon)) rloc(mtmp);
  1595. X              /* "Good hunting, brother" */
  1596. X            else {
  1597. X# endif
  1598. X                mtmp->minvis = 0;
  1599. X                /* Why?  For the same reason in real demon talk */
  1600. X                pline("%s gets angry.", Xmonnam(mtmp));
  1601. X                mtmp->mpeaceful = 0;
  1602. X                /* since no way is an image going to pay it off */
  1603. X# ifdef POLYSELF
  1604. X            }
  1605. X# endif
  1606. X        } else if(demon_talk(mtmp)) return(1);    /* you paid it off */
  1607. X    }
  1608. X#endif
  1609. X
  1610. X/*    Now the actual movement phase    */
  1611. X
  1612. X    if(!nearby || mtmp->mflee || scared ||
  1613. X       mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) ||
  1614. X       (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) ||
  1615. X       (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) ||
  1616. X       (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) {
  1617. X
  1618. X        tmp = m_move(mtmp, 0);
  1619. X        distfleeck(mtmp,&inrange,&nearby,&scared);    /* recalc */
  1620. X
  1621. X        switch (tmp) {
  1622. X
  1623. X            case 0:    /* no movement, but it can still attack you */
  1624. X            case 3:    /* absolutely no movement */
  1625. X                /* for pets, case 0 and 3 are equivalent */
  1626. X             /* During hallucination, monster appearance should
  1627. X              * still change - even if it doesn't move.
  1628. X               */
  1629. X             if(Hallucination) pmon(mtmp);
  1630. X             break;
  1631. X             case 1:    /* monster moved */
  1632. X            /* Maybe it stepped on a trap and fell asleep... */
  1633. X            if(mtmp->msleep || !mtmp->mcanmove) return(0);
  1634. X             if(!nearby && ranged_attk(mdat)) break;
  1635. X             else if(mdat->mmove <= 12) return(0);
  1636. X             break;
  1637. X             case 2:    /* monster died */
  1638. X             return(1);
  1639. X         }
  1640. X    }
  1641. X
  1642. X/*    Now, attack the player if possible - one attack set per monst    */
  1643. X
  1644. X    if(inrange && !noattacks(mdat) &&
  1645. X       !mtmp->mpeaceful && !mtmp->mtame && u.uhp > 0 && !scared && tmp != 3)
  1646. X        if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */
  1647. X
  1648. X#ifdef WORM
  1649. X    if(mtmp->wormno && !mtmp->mtame) wormhit(mtmp);
  1650. X#endif
  1651. X
  1652. X    /* extra emotional attack for vile monsters */
  1653. X    if(inrange && mtmp->data->msound == MS_CUSS &&
  1654. X       !mtmp->minvis && !mtmp->mpeaceful && !rn2(5))
  1655. X        cuss(mtmp);
  1656. X
  1657. X    /* extra movement for fast monsters */
  1658. X    if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp, 1);
  1659. X    return(tmp == 2);
  1660. X}
  1661. X
  1662. Xstatic const char NEARDATA practical[] = { WEAPON_SYM, GEM_SYM, FOOD_SYM, 0 };
  1663. Xstatic const char NEARDATA magical[] = {
  1664. X    AMULET_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM, RING_SYM,
  1665. X#ifdef SPELLS
  1666. X    SPBOOK_SYM,
  1667. X#endif
  1668. X    0 };
  1669. Xstatic const char NEARDATA indigestion[] = { BALL_SYM, ROCK_SYM, 0 };
  1670. X
  1671. X#endif /* OVL1 */
  1672. X#ifdef OVL0
  1673. X
  1674. X#ifdef POLYSELF
  1675. Xstatic boolean
  1676. Xitsstuck(mtmp)
  1677. Xregister struct monst *mtmp;
  1678. X{
  1679. X    if (sticks(uasmon) && mtmp==u.ustuck && !u.uswallow) {
  1680. X        kludge("%s cannot escape from you!", Monnam(mtmp));
  1681. X        return(TRUE);
  1682. X    }
  1683. X    return(FALSE);
  1684. X}
  1685. X#endif
  1686. X
  1687. Xint
  1688. Xm_move(mtmp, after)
  1689. Xregister struct monst *mtmp;
  1690. Xregister int after;
  1691. X{
  1692. X    register struct monst *mtmp2;
  1693. X    register int nx,ny,omx,omy,appr,nearer,cnt,i,j;
  1694. X    xchar gx,gy,nix,niy,chcnt;
  1695. X    schar chi;
  1696. X    boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0;
  1697. X    boolean likerock=0, can_tunnel=0;
  1698. X    boolean can_open=0, can_unlock=0, doorbuster=0;
  1699. X    struct permonst *ptr = mtmp->data;
  1700. X    schar mmoved = 0;    /* not strictly nec.: chi >= 0 will do */
  1701. X    coord poss[9];
  1702. X    long info[9];
  1703. X    long flag;
  1704. X
  1705. X    if(mtmp->mtrapped) {
  1706. X        i = mintrap(mtmp);
  1707. X        if(i == 2) return(2);    /* it died */
  1708. X        if(i == 1) return(0);    /* still in trap, so didn't move */
  1709. X    }
  1710. X    if(mtmp->mhide &&
  1711. X       (OBJ_AT(mtmp->mx, mtmp->my) || levl[mtmp->mx][mtmp->my].gmask) &&
  1712. X       rn2(10))
  1713. X        return(0);        /* do not leave hiding place */
  1714. X    if(mtmp->meating) {
  1715. X        mtmp->meating--;
  1716. X        return(3);            /* still eating */
  1717. X    }
  1718. X
  1719. X    set_apparxy(mtmp);
  1720. X    /* where does mtmp think you are? */
  1721. X    /* Not necessary if m_move called from this file, but necessary in
  1722. X     * other calls of m_move (ex. leprechauns dodging)
  1723. X     */
  1724. X    can_tunnel = tunnels(ptr) &&
  1725. X#ifdef REINCARNATION
  1726. X             dlevel != rogue_level &&
  1727. X#endif
  1728. X             (!needspick(ptr) || m_carrying(mtmp, PICK_AXE));
  1729. X    can_open = !(nohands(ptr) || verysmall(ptr));
  1730. X    can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) || mtmp->iswiz);
  1731. X    doorbuster = is_giant(ptr);
  1732. X#ifdef WORM
  1733. X    if(mtmp->wormno) goto not_special;
  1734. X#endif
  1735. X    /* my dog gets special treatment */
  1736. X    if(mtmp->mtame) {
  1737. X        mmoved = dog_move(mtmp, after);
  1738. X        goto postmov;
  1739. X    }
  1740. X
  1741. X    /* likewise for shopkeeper */
  1742. X    if(mtmp->isshk) {
  1743. X        mmoved = shk_move(mtmp);
  1744. X        if(mmoved == -2) return(2);
  1745. X        if(mmoved >= 0) goto postmov;
  1746. X        mmoved = 0;        /* follow player outside shop */
  1747. X    }
  1748. X
  1749. X    /* and for the guard */
  1750. X    if(mtmp->isgd) {
  1751. X        mmoved = gd_move(mtmp);
  1752. X        if(mmoved == -2) return(2);
  1753. X        if(mmoved >= 0) goto postmov;
  1754. X        mmoved = 0;
  1755. X    }
  1756. X
  1757. X    /* and the wiz already got special treatment */
  1758. X    if(mtmp->iswiz) {
  1759. X        mmoved = 0;
  1760. X        goto postmov;
  1761. X    }
  1762. X#if defined(ALTARS) && defined(THEOLOGY)
  1763. X    /* and for the priest */
  1764. X    if(mtmp->ispriest) {
  1765. X        mmoved = pri_move(mtmp);
  1766. X        if(mmoved == -2) return(2);
  1767. X        if(mmoved >= 0) goto postmov;
  1768. X        mmoved = 0;
  1769. X    }
  1770. X#endif
  1771. X#ifdef MAIL
  1772. X    if(ptr == &mons[PM_MAIL_DAEMON]) {
  1773. X        if(flags.soundok && canseemon(mtmp))
  1774. X        verbalize("I'm late!");
  1775. X        mongone(mtmp);
  1776. X        return(2);        
  1777. X    }
  1778. X#endif
  1779. X    /* teleport if that lies in our nature */
  1780. X    if(ptr == &mons[PM_TENGU] && !rn2(5)) {
  1781. X        if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2))
  1782. X        rloc(mtmp);
  1783. X        else
  1784. X        mnexto(mtmp);
  1785. X        mmoved = 1;
  1786. X        goto postmov;
  1787. X    }
  1788. X#ifdef WORM
  1789. Xnot_special:
  1790. X#endif
  1791. X    if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
  1792. X    appr = 1;
  1793. X    if(mtmp->mflee) appr = -1;
  1794. X    if(mtmp->mconf || (Invis && !perceives(ptr)) ||  !mtmp->mcansee ||
  1795. X#ifdef POLYSELF
  1796. X       (u.usym == S_MIMIC_DEF) || u.uundetected ||
  1797. X#endif
  1798. X       (mtmp->mpeaceful && !mtmp->isshk) ||    /* allow shks to follow */
  1799. X       ((ptr->mlet == S_STALKER || ptr->mlet == S_BAT ||
  1800. X         ptr->mlet == S_YLIGHT) && !rn2(3)))
  1801. X        appr = 0;
  1802. X    omx = mtmp->mx;
  1803. X    omy = mtmp->my;
  1804. X    gx = mtmp->mux;
  1805. X    gy = mtmp->muy;
  1806. X    if(ptr == &mons[PM_LEPRECHAUN] && appr == 1 && mtmp->mgold > u.ugold)
  1807. X        appr = -1;
  1808. X
  1809. X    if(can_track(ptr)) {
  1810. X        register coord *cp;
  1811. X        schar mroom;
  1812. X
  1813. X        mroom = inroom(omx,omy);
  1814. X        if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
  1815. X        cp = gettrack(omx,omy);
  1816. X        if(cp){
  1817. X            gx = cp->x;
  1818. X            gy = cp->y;
  1819. X        }
  1820. X        }
  1821. X    }
  1822. X
  1823. X#ifdef REINCARNATION
  1824. X    if (dlevel != rogue_level)
  1825. X#endif
  1826. X    {
  1827. X        register int pctload = (curr_mon_load(mtmp) * 100) /
  1828. X            max_mon_load(mtmp);
  1829. X
  1830. X        /* look for gold or jewels nearby */
  1831. X        likegold = (likes_gold(ptr) && pctload < 95);
  1832. X        likegems = (likes_gems(ptr) && pctload < 85);
  1833. X        likeobjs = (likes_objs(ptr) && pctload < 75);
  1834. X        likemagic = (likes_magic(ptr) && pctload < 85);
  1835. X        likerock = (throws_rocks(ptr) && pctload < 50);
  1836. X        conceals = hides_under(ptr);
  1837. X    }
  1838. X
  1839. X#define SQSRCHRADIUS    5
  1840. X#define    SRCHRADIUS    (SQSRCHRADIUS*SQSRCHRADIUS)
  1841. X
  1842. X      { xchar mind = SRCHRADIUS;        /* not too far away */
  1843. X    register int dd;
  1844. X
  1845. X    /* cut down the search radius if it thinks character is closer. */
  1846. X    if(dist2(mtmp->mux, mtmp->muy, omx, omy) < SRCHRADIUS &&
  1847. X        !mtmp->mtame && !mtmp->mpeaceful)     mind /= 2;
  1848. X
  1849. X    if(likegold){
  1850. X        register struct gold *gold;
  1851. X
  1852. X        for(gold = fgold; gold; gold = gold->ngold)
  1853. X        if((dd = dist2(omx,omy,gold->gx,gold->gy)) < mind){
  1854. X            mind = dd;
  1855. X            gx = gold->gx;
  1856. X            gy = gold->gy;
  1857. X        }
  1858. X    }
  1859. X    if((likegems || likeobjs || likemagic || likerock || conceals)
  1860. X          && (!in_shop(omx, omy) || (!rn2(25) && !mtmp->isshk))) {
  1861. X        register struct obj *otmp;
  1862. X        register int xx, yy;
  1863. X
  1864. X        for(xx = omx-SQSRCHRADIUS; xx <= omx+SQSRCHRADIUS; xx++) {
  1865. X        for(yy = omy-SQSRCHRADIUS; yy <= omy+SQSRCHRADIUS; yy++) {
  1866. X            if(!isok(xx, yy)) continue;
  1867. X            if((dd = dist2(omx,omy,xx, yy)) >= mind) continue;
  1868. X            for(otmp = level.objects[xx][yy]; otmp; otmp = otmp->nexthere)
  1869. X              if((likeobjs && index(practical, otmp->olet)) ||
  1870. X             (likemagic && index(magical, otmp->olet)) ||
  1871. X             (likerock && otmp->otyp == BOULDER) ||
  1872. X             (likegems && otmp->olet == GEM_SYM &&
  1873. X              otmp->otyp < LAST_GEM + 6) ||
  1874. X             (conceals && !cansee(otmp->ox,otmp->oy)) ||
  1875. X             (ptr == &mons[PM_GELATINOUS_CUBE] &&
  1876. X              !index(indigestion, otmp->olet))
  1877. X             ) {
  1878. X              if(can_carry(mtmp,otmp))
  1879. X                if(ptr->mlet != S_UNICORN ||
  1880. X                   objects[otmp->otyp].g_val != 0){
  1881. X                mind = dd;
  1882. X                gx = otmp->ox;
  1883. X                gy = otmp->oy;
  1884. X                break;
  1885. X                }
  1886. X              }
  1887. X        }
  1888. X        }
  1889. X    }
  1890. X    if(mind < SRCHRADIUS && appr == -1) {
  1891. X        if(dist2(omx,omy,mtmp->mux,mtmp->muy) < 10) {
  1892. X        gx = mtmp->mux;
  1893. X        gy = mtmp->muy;
  1894. X        } else
  1895. X        appr = 1;
  1896. X    }
  1897. X      }
  1898. X    nix = omx;
  1899. X    niy = omy;
  1900. X    flag = ALLOW_TRAPS;
  1901. X    if (mtmp->mpeaceful) flag |= (ALLOW_SANCT | ALLOW_SSM);
  1902. X    else flag |= ALLOW_U;
  1903. X    if (ptr->mlet == S_UNICORN) flag |= NOTONL;
  1904. X    if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK);
  1905. X    if (can_tunnel) flag |= ALLOW_DIG;
  1906. X    if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) flag |= ALLOW_SSM;
  1907. X    if (is_undead(ptr)) flag |= NOGARLIC;
  1908. X    if (throws_rocks(ptr)) flag |= ALLOW_ROCK;
  1909. X    if (can_open) flag |= OPENDOOR;
  1910. X    if (can_unlock) flag |= UNLOCKDOOR;
  1911. X    if (doorbuster) flag |= BUSTDOOR;
  1912. X    cnt = mfndpos(mtmp, poss, info, flag);
  1913. X    chcnt = 0;
  1914. X    chi = -1;
  1915. X
  1916. X    for(i=0; i < cnt; i++) {
  1917. X        nx = poss[i].x;
  1918. X        ny = poss[i].y;
  1919. X
  1920. X        if (appr != 0) for(j=0; j < MTSZ && j < cnt-1; j++)
  1921. X        if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
  1922. X            if(rn2(4*(cnt-j))) goto nxti;
  1923. X
  1924. X        nearer = (dist2(nx,ny,gx,gy) < dist2(nix,niy,gx,gy));
  1925. X
  1926. X        if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
  1927. X               (!appr && !rn2(++chcnt)) || !mmoved) {
  1928. X        nix = nx;
  1929. X        niy = ny;
  1930. X        chi = i;
  1931. X        mmoved = 1;
  1932. X        }
  1933. X    nxti:    ;
  1934. X    }
  1935. X
  1936. X    if(mmoved) {
  1937. X#ifdef POLYSELF
  1938. X        if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
  1939. X        return(3);
  1940. X#endif
  1941. X        if((info[chi] & ALLOW_U) || (nix == u.ux && niy == u.uy)) {
  1942. X        mtmp->mux = u.ux;
  1943. X        mtmp->muy = u.uy;
  1944. X        return(0);
  1945. X        }
  1946. X        /* The monster may attack another based on 1 of 2 conditions:
  1947. X         * 1 - He may be under the "conflict" influence.
  1948. X         * 2 - He may mistake the monster for your (displaced) image.
  1949. X         * Pets get taken care of above and shouldn't reach this code.
  1950. X         */
  1951. X        if((info[chi] & ALLOW_M) ||
  1952. X           (nix == mtmp->mux && niy == mtmp->muy)) {
  1953. X        int stat;
  1954. X        mtmp2 = m_at(nix,niy);
  1955. X        if((stat = mattackm(mtmp, mtmp2)) == 1 && rn2(4) &&
  1956. X            mtmp2->mlstmv != moves && mattackm(mtmp2, mtmp) == 2)
  1957. X            return(2);
  1958. X        if(stat == -1) return(2);
  1959. X        return(3);
  1960. X        }
  1961. X#ifdef WORM
  1962. X        /* The square now has a worm segment and must keep its MON_AT() state */
  1963. X        if (!mtmp->wormno)
  1964. X#endif
  1965. X            remove_monster(omx, omy);
  1966. X        place_monster(mtmp, nix, niy);
  1967. X        for(j = MTSZ-1; j > 0; j--)
  1968. X        mtmp->mtrack[j] = mtmp->mtrack[j-1];
  1969. X        mtmp->mtrack[0].x = omx;
  1970. X        mtmp->mtrack[0].y = omy;
  1971. X#ifdef WORM
  1972. X        if(mtmp->wormno) worm_move(mtmp);
  1973. X#endif
  1974. X    } else {
  1975. X        if(ptr->mlet == S_UNICORN && rn2(2)) {
  1976. X        rloc(mtmp);
  1977. X        return(1);
  1978. X        }
  1979. X#ifdef WORM
  1980. X        if(mtmp->wormno) worm_nomove(mtmp);
  1981. X#endif
  1982. X    }
  1983. Xpostmov:
  1984. X    if(mmoved == 1) {
  1985. X        boolean canseeit = cansee(mtmp->mx, mtmp->my);
  1986. X        boolean abstain = (mtmp->mpeaceful && !mtmp->mtame);
  1987. X
  1988. X        if(mintrap(mtmp) == 2) return(2);    /* he died */
  1989. X
  1990. X        /* open a door, or crash through it, if you can */
  1991. X        if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
  1992. X            && !passes_walls(ptr) /* doesn't need to open doors */
  1993. X            && !can_tunnel /* taken care of below */
  1994. X          ) {
  1995. X        struct rm *here = &levl[mtmp->mx][mtmp->my];
  1996. X        boolean btrapped = (here->doormask & D_TRAPPED);
  1997. X
  1998. X        if(here->doormask & (D_LOCKED|D_CLOSED) && amorphous(ptr)) {
  1999. X            if (flags.verbose && canseeit)
  2000. X            pline("%s %ss under the door.", Monnam(mtmp),
  2001. X                  ptr == &mons[PM_FOG_CLOUD] ? "flow" : "ooze");
  2002. X        } else if(here->doormask & D_LOCKED && can_unlock) {
  2003. X            if(btrapped) {
  2004. X            here->doormask = D_NODOOR;
  2005. X            mnewsym(mtmp->mx, mtmp->my);
  2006. X            if (canseeit) prl(mtmp->mx,mtmp->my);
  2007. X            if(mb_trapped(mtmp)) return(2);
  2008. X            } else {
  2009. X            if (flags.verbose) {
  2010. X                if (canseeit)
  2011. X                  You("see a door being unlocked and opened.");
  2012. X                else if (flags.soundok)
  2013. X                   You("hear a door being unlocked and opened.");
  2014. X                }
  2015. X                here->doormask = D_ISOPEN;
  2016. X            mnewsym(mtmp->mx, mtmp->my);
  2017. X            if (canseeit) prl(mtmp->mx,mtmp->my);
  2018. X            }
  2019. X        } else if (here->doormask == D_CLOSED && can_open) {
  2020. X            if(btrapped) {
  2021. X            here->doormask = D_NODOOR;
  2022. X            mnewsym(mtmp->mx, mtmp->my);
  2023. X            if (canseeit) prl(mtmp->mx,mtmp->my);
  2024. X            if(mb_trapped(mtmp)) return(2);
  2025. X            } else {
  2026. X                if (flags.verbose) {
  2027. X                if (canseeit)
  2028. X                     You("see a door being opened.");
  2029. X                else if (flags.soundok)
  2030. X                     You("hear the sound of a door opening.");
  2031. X                }
  2032. X                here->doormask = D_ISOPEN;
  2033. X            mnewsym(mtmp->mx, mtmp->my);
  2034. X            if (canseeit) prl(mtmp->mx,mtmp->my);
  2035. X            }
  2036. X        } else if (here->doormask & (D_LOCKED|D_CLOSED)) {
  2037. X               /* mfndpos guarantees this must be a doorbuster */
  2038. X            if(btrapped) {
  2039. X            here->doormask = D_NODOOR;
  2040. X            mnewsym(mtmp->mx, mtmp->my);
  2041. X            if (canseeit) prl(mtmp->mx,mtmp->my);
  2042. X            if(mb_trapped(mtmp)) return(2);
  2043. X            } else {
  2044. X                if (flags.verbose) {
  2045. X                if (canseeit)
  2046. X                    You("see a door crash open.");
  2047. X                else if (flags.soundok)
  2048. X                    You("hear the sound of a door crashing open.");
  2049. X                }
  2050. X                if (here->doormask & D_LOCKED && !rn2(2))
  2051. X                    here->doormask = D_NODOOR;
  2052. X                else here->doormask = D_BROKEN;
  2053. X            mnewsym(mtmp->mx, mtmp->my);
  2054. X            if (canseeit) prl(mtmp->mx,mtmp->my);
  2055. X            }
  2056. X        }
  2057. X          }
  2058. X        /* Maybe a rock mole just ate something? */
  2059. X        if(can_tunnel) if(!mdig_tunnel(mtmp)) return(2); /* died? */
  2060. X
  2061. X        if(levl[mtmp->mx][mtmp->my].gmask == TRUE) {
  2062. X        /* Maybe a rock mole just ate some gold */
  2063. X        if(metallivorous(ptr)) meatgold(mtmp);
  2064. X        if(likegold && (!abstain || !rn2(10))) mpickgold(mtmp);
  2065. X        }
  2066. X        if(OBJ_AT(mtmp->mx, mtmp->my)) {
  2067. X        /* Maybe a rock mole just ate some metal object */
  2068. X        if(metallivorous(ptr)) meatgold(mtmp);
  2069. X        /* Maybe a cube ate just about anything */
  2070. X        if(ptr == &mons[PM_GELATINOUS_CUBE]) meatobj(mtmp);
  2071. X
  2072. X        if ((!abstain || !rn2(10)) 
  2073. X            && (!in_shop(mtmp->mx, mtmp->my) || !rn2(25))) {
  2074. X            if(likeobjs) mpickstuff(mtmp, practical);
  2075. X            if(likemagic) mpickstuff(mtmp, magical);
  2076. X            if(likerock || likegems) mpickgems(mtmp);
  2077. X        }
  2078. X        }
  2079. X        if(mtmp->mhide) mtmp->mundetected = (OBJ_AT(mtmp->mx, mtmp->my)
  2080. X                    || levl[mtmp->mx][mtmp->my].gmask);
  2081. X
  2082. X        /* set also in domove(), hack.c */
  2083. X        if(u.uswallow && mtmp == u.ustuck) {
  2084. X        u.ux = mtmp->mx;
  2085. X        u.uy = mtmp->my;
  2086. X            if(mtmp->mx != mtmp->mdx || mtmp->my != mtmp->mdy) {
  2087. X            swallowed(0);
  2088. X            newsym(mtmp->mdx,mtmp->mdy);
  2089. X            mtmp->mdx = mtmp->mx;
  2090. X            mtmp->mdy = mtmp->my;
  2091. X        }
  2092. X        }
  2093. X        pmon(mtmp);
  2094. X    }
  2095. X    return(mmoved);
  2096. X}
  2097. X
  2098. X#endif /* OVL0 */
  2099. X#ifdef OVL2
  2100. X
  2101. Xboolean
  2102. Xclosed_door(x, y)
  2103. Xregister int x, y;
  2104. X{
  2105. X    return(IS_DOOR(levl[x][y].typ) &&
  2106. X            (levl[x][y].doormask & (D_LOCKED | D_CLOSED)));
  2107. X}
  2108. X
  2109. Xboolean
  2110. Xaccessible(x, y)
  2111. Xregister int x, y;
  2112. X{
  2113. X    return(ACCESSIBLE(levl[x][y].typ) && !closed_door(x, y));
  2114. X}
  2115. X
  2116. X#endif /* OVL2 */
  2117. X#ifdef OVL1
  2118. X
  2119. Xvoid
  2120. Xset_apparxy(mtmp)        /* where does mtmp think you are standing? */
  2121. X    register struct monst *mtmp;
  2122. X{
  2123. X#define notseen (Invis && !perceives(mtmp->data))
  2124. X/*    add cases as required.  eg. Displacement ... */
  2125. X    register int disp = (notseen ? 1 : Displaced ? 2 : 0);
  2126. X
  2127. X/*     without something like the following, invis. and displ. are too */
  2128. X/*    powerful. */
  2129. X    register boolean gotu =
  2130. X        (notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE);
  2131. X
  2132. X/*    Monsters which know where you are don't suddenly forget, if you
  2133. X    didn't move away. */
  2134. X    if (mtmp->mux==u.ux && mtmp->muy==u.uy) gotu = 1;
  2135. X
  2136. X/*     your dog follows your smell */
  2137. X    if(!disp || mtmp->mtame || gotu ||
  2138. X/*    If invisible but not displaced, staying around gets you 'discovered' */
  2139. X        (!Displaced && u.dx == 0 && u.dy == 0)) {
  2140. X        mtmp->mux = u.ux;
  2141. X        mtmp->muy = u.uy;
  2142. X    }
  2143. X    else do {
  2144. X        mtmp->mux = u.ux - disp + rn2(2*disp+1);
  2145. X        mtmp->muy = u.uy - disp + rn2(2*disp+1);
  2146. X    } while((mtmp->mux != u.ux || mtmp->muy != u.uy) &&
  2147. X            ( (!passes_walls(mtmp->data) &&
  2148. X              (!ACCESSIBLE(levl[mtmp->mux][mtmp->muy].typ) ||
  2149. X               (closed_door(mtmp->mux, mtmp->muy) &&
  2150. X            !amorphous(mtmp->data)
  2151. X               )
  2152. X              )
  2153. X          ) ||
  2154. X          (disp==1 && mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my)
  2155. X            )
  2156. X           );
  2157. X}
  2158. X
  2159. X#endif /* OVL1 */
  2160. X#ifdef OVLB
  2161. X
  2162. X#ifdef STUPID_CPP    /* otherwise these functions are macros in rm.h */
  2163. X/*
  2164. X * Functions for encapsulation of level.monsters references.
  2165. X */
  2166. Xboolean
  2167. XMON_AT(x, y)
  2168. Xint x, y;
  2169. X{
  2170. X    return(level.monsters[x][y] != (struct monst *)0);
  2171. X}
  2172. X
  2173. Xvoid place_monster(mtmp, x, y)
  2174. Xregister struct monst *mtmp;
  2175. Xint x, y;
  2176. X{
  2177. X    level.monsters[x][y] = mtmp;
  2178. X    mtmp->mx = x;
  2179. X    mtmp->my = y;
  2180. X}
  2181. X
  2182. Xvoid place_worm_seg(mtmp, x, y)
  2183. Xregister struct monst *mtmp;
  2184. Xint x, y;
  2185. X{
  2186. X    level.monsters[x][y] = mtmp;
  2187. X}
  2188. X
  2189. Xvoid remove_monster(x, y)
  2190. Xint x, y;
  2191. X{
  2192. X    level.monsters[x][y] = (struct monst *)0;
  2193. X}
  2194. X
  2195. Xstruct monst *m_at(x, y)
  2196. Xint x, y;
  2197. X{
  2198. X    return(level.monsters[x][y]);
  2199. X}
  2200. X#endif    /* STUPID_CPP */
  2201. X
  2202. X#endif /* OVLB */
  2203. END_OF_FILE
  2204. if test 24074 -ne `wc -c <'src/monmove.c'`; then
  2205.     echo shar: \"'src/monmove.c'\" unpacked with wrong size!
  2206. fi
  2207. # end of 'src/monmove.c'
  2208. fi
  2209. if test -f 'src/rip.c' -a "${1}" != "-c" ; then 
  2210.   echo shar: Will not clobber existing file \"'src/rip.c'\"
  2211. else
  2212. echo shar: Extracting \"'src/rip.c'\" \(2319 characters\)
  2213. sed "s/^X//" >'src/rip.c' <<'END_OF_FILE'
  2214. X/*    SCCS Id: @(#)rip.c    3.0    88/04/27
  2215. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2216. X/* NetHack may be freely redistributed.  See license for details. */
  2217. X
  2218. X#include "hack.h"
  2219. X
  2220. Xstatic void FDECL(center,(int,char *));
  2221. X
  2222. Xstatic const char *rip_txt[] = {
  2223. X"                       ----------",
  2224. X"                      /          \\",
  2225. X"                     /    REST    \\",
  2226. X"                    /      IN      \\",
  2227. X"                   /     PEACE      \\",
  2228. X"                  /                  \\",
  2229. X"                  |                  |",
  2230. X"                  |                  |",
  2231. X"                  |                  |",
  2232. X"                  |                  |",
  2233. X"                  |                  |",
  2234. X"                  |       1001       |",
  2235. X"                 *|     *  *  *      | *",
  2236. X"        _________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n",
  2237. X0
  2238. X};
  2239. X
  2240. Xchar **rip;
  2241. X
  2242. Xstatic void
  2243. Xcenter(line, text)
  2244. Xint line;
  2245. Xchar *text;
  2246. X{
  2247. X    register char *ip,*op;
  2248. X    ip = text;
  2249. X    op = &rip[line][28 - ((strlen(text)+1)>>1)];
  2250. X    while(*ip) *op++ = *ip++;
  2251. X}
  2252. X
  2253. Xvoid
  2254. Xoutrip(){
  2255. X    register char **dp;
  2256. X    register char *dpx;
  2257. X    char buf[BUFSZ];
  2258. X    register int x, y;
  2259. X    int killed_by_line = 0;
  2260. X
  2261. X    rip = dp = (char **) alloc(sizeof(rip_txt));
  2262. X    if (!dp) return;
  2263. X    for (x = 0; rip_txt[x]; x++) {
  2264. X        dp[x] = (char *) alloc((unsigned int)(strlen(rip_txt[x]) + 1));
  2265. X        if (!dp[x]) return;
  2266. X        Strcpy(dp[x], rip_txt[x]);
  2267. X    }
  2268. X    dp[x] = (char *)0;
  2269. X
  2270. X    cls();
  2271. X    Sprintf(buf, "%s", plname);
  2272. X    buf[16] = 0;
  2273. X    center(6, buf);
  2274. X    Sprintf(buf, "%ld Au", u.ugold);
  2275. X    center(7, buf);
  2276. X    if (killer_format != NO_KILLER_PREFIX) {
  2277. X        killed_by_line = 1;
  2278. X        Strcpy(buf, "killed by");
  2279. X        if (killer_format == KILLED_BY_AN)
  2280. X            Strcat(buf, index(vowels, *killer) ? " an" : " a");
  2281. X        center(8, buf);
  2282. X    }
  2283. X    Strcpy(buf, killer);
  2284. X    if(strlen(buf) > 16) {
  2285. X        register int i,i0,i1;
  2286. X        i0 = i1 = 0;
  2287. X        for(i = 0; i <= 16; i++)
  2288. X            if(buf[i] == ' ') i0 = i, i1 = i+1;
  2289. X        if(!i0) i0 = i1 = 16;
  2290. X        buf[i1 + 16] = 0;
  2291. X        center(9 + killed_by_line, buf+i1);
  2292. X        buf[i0] = 0;
  2293. X    }
  2294. X    center(8 + killed_by_line, buf);
  2295. X    Sprintf(buf, "%4d", getyear());
  2296. X    center(11, buf);
  2297. X    for(y=8; *dp; y++,dp++){
  2298. X        x = 0;
  2299. X        dpx = *dp;
  2300. X        while(dpx[x]) {
  2301. X            while(dpx[x] == ' ') x++;
  2302. X            curs(x,y);
  2303. X            while(dpx[x] && dpx[x] != ' '){
  2304. X                if(done_stopprint)
  2305. X                    return;
  2306. X                curx++;
  2307. X                (void) putchar(dpx[x++]);
  2308. X            }
  2309. X        }
  2310. X    }
  2311. X    getret();
  2312. X}
  2313. X
  2314. END_OF_FILE
  2315. if test 2319 -ne `wc -c <'src/rip.c'`; then
  2316.     echo shar: \"'src/rip.c'\" unpacked with wrong size!
  2317. fi
  2318. # end of 'src/rip.c'
  2319. fi
  2320. echo shar: End of archive 32 \(of 56\).
  2321. cp /dev/null ark32isdone
  2322. MISSING=""
  2323. 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
  2324.     if test ! -f ark${I}isdone ; then
  2325.     MISSING="${MISSING} ${I}"
  2326.     fi
  2327. done
  2328. if test "${MISSING}" = "" ; then
  2329.     echo You have unpacked all 56 archives.
  2330.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2331. else
  2332.     echo You still need to unpack the following archives:
  2333.     echo "        " ${MISSING}
  2334. fi
  2335. ##  End of shell archive.
  2336. exit 0
  2337.