abstract
| - Below is the full text to mklev.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mklev.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)mklev.c 3.0 88/11/24 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. /* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */ 8. /* croom->lx etc are schar (width <= int), so % arith ensures that */ 9. /* conversion of result to int is reasonable */ 10. 11. #ifdef SINKS 12. static void mksink(); 13. #endif 14. #ifdef ALTARS 15. static void mkaltar(); 16. #endif 17. 18. int 19. somex(croom) 20. register struct mkroom *croom; 21. { 22. return rn2(croom->hx-croom->lx+1) + croom->lx; 23. } 24. 25. int 26. somey(croom) 27. register struct mkroom *croom; 28. { 29. return rn2(croom->hy-croom->ly+1) + croom->ly; 30. } 31. 32. #define XLIM 4 /* define minimum required space around a room */ 33. #define YLIM 3 34. boolean secret; /* TRUE while making a vault: increase [XY]LIM */ 35. struct rm zerorm; 36. schar nxcor; 37. boolean goldseen; 38. 39. /* Definitions used by makerooms() and addrs() */ 40. #define MAXRS 50 /* max lth of temp rectangle table - arbitrary */ 41. struct rectangle { 42. xchar rlx,rly,rhx,rhy; 43. } rs[MAXRS+1]; 44. int rscnt,rsmax; /* 0..rscnt-1: currently under consideration */ 45. /* rscnt..rsmax: discarded */ 46. 47. static void 48. addrsx(lx,ly,hx,hy,discarded) 49. register int lx,ly,hx,hy; 50. boolean discarded; /* piece of a discarded area */ 51. { 52. register struct rectangle *rsp; 53. 54. /* check inclusions */ 55. for(rsp = rs; rsp < &rs[rsmax]; rsp++) { 56. if(lx >= rsp->rlx && hx <= rsp->rhx && 57. ly >= rsp->rly && hy <= rsp->rhy) 58. return; 59. } 60. 61. /* make a new entry */ 62. if(rsmax >= MAXRS) { 63. #ifdef WIZARD 64. if(wizard) pline("MAXRS may be too small."); 65. #endif 66. return; 67. } 68. rsmax++; 69. if(!discarded) { 70. *rsp = rs[rscnt]; 71. rsp = &rs[rscnt]; 72. rscnt++; 73. } 74. rsp->rlx = lx; 75. rsp->rly = ly; 76. rsp->rhx = hx; 77. rsp->rhy = hy; 78. } 79. 80. static void 81. addrs(lowx,lowy,hix,hiy) 82. register int lowx,lowy,hix,hiy; 83. { 84. register struct rectangle *rsp; 85. register int lx,ly,hx,hy,xlim,ylim; 86. boolean discarded; 87. 88. xlim = XLIM + secret; 89. ylim = YLIM + secret; 90. 91. /* walk down since rscnt and rsmax change */ 92. for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) { 93. 94. if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy || 95. (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy) 96. continue; 97. if((discarded = (rsp >= &rs[rscnt]))) { 98. *rsp = rs[--rsmax]; 99. } else { 100. rsmax--; 101. rscnt--; 102. *rsp = rs[rscnt]; 103. if(rscnt != rsmax) 104. rs[rscnt] = rs[rsmax]; 105. } 106. if(lowy - ly > 2*ylim + 4) 107. addrsx(lx,ly,hx,lowy-2,discarded); 108. if(lowx - lx > 2*xlim + 4) 109. addrsx(lx,ly,lowx-2,hy,discarded); 110. if(hy - hiy > 2*ylim + 4) 111. addrsx(lx,hiy+2,hx,hy,discarded); 112. if(hx - hix > 2*xlim + 4) 113. addrsx(hix+2,ly,hx,hy,discarded); 114. } 115. } 116. 117. static int 118. comp(x,y) 119. register struct mkroom *x,*y; 120. { 121. if(x->lx < y->lx) return(-1); 122. return(x->lx > y->lx); 123. } 124. 125. static void 126. finddpos(cc, xl,yl,xh,yh) 127. coord *cc; 128. xchar xl,yl,xh,yh; 129. { 130. register xchar x, y; 131. 132. x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); 133. y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); 134. if(okdoor(x, y)) 135. goto gotit; 136. 137. for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 138. if(okdoor(x, y)) 139. goto gotit; 140. 141. for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 142. if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR) 143. goto gotit; 144. /* cannot find something reasonable -- strange */ 145. x = xl; 146. y = yh; 147. gotit: 148. cc->x = x; 149. cc->y = y; 150. return; 151. } 152. 153. /* Only called from makerooms() and makebigroom() */ 154. static int 155. maker(lowx,ddx,lowy,ddy,lit) 156. schar lowx,ddx,lowy,ddy; 157. boolean lit; 158. { 159. register struct mkroom *croom; 160. register int x, y, hix = lowx+ddx, hiy = lowy+ddy; 161. register int xlim = XLIM + secret, ylim = YLIM + secret; 162. 163. if(nroom >= MAXNROFROOMS) return(0); 164. if(lowx < XLIM) lowx = XLIM; 165. if(lowy < YLIM) lowy = YLIM; 166. if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1; 167. if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1; 168. chk: 169. if(hix <= lowx || hiy <= lowy) return(0); 170. 171. /* check area around room (and make room smaller if necessary) */ 172. for(x = lowx - xlim; x <= hix + xlim; x++) { 173. for(y = lowy - ylim; y <= hiy + ylim; y++) { 174. if(levl[x][y].typ) { 175. #ifdef WIZARD 176. if(wizard && !secret) 177. pline("Strange area [%d,%d] in maker().",x,y); 178. #endif 179. if(!rn2(3)) return(0); 180. if(x < lowx) 181. lowx = x+xlim+1; 182. else 183. hix = x-xlim-1; 184. if(y < lowy) 185. lowy = y+ylim+1; 186. else 187. hiy = y-ylim-1; 188. goto chk; 189. } 190. } 191. } 192. 193. croom = &rooms[nroom]; 194. 195. /* on low levels the room is lit (usually) */ 196. /* secret vaults are always lit */ 197. /* some other rooms may require lighting */ 198. if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) { 199. for(x = lowx-1; x <= hix+1; x++) 200. for(y = lowy-1; y <= hiy+1; y++) 201. levl[x][y].lit = 1; 202. croom->rlit = 1; 203. } else 204. croom->rlit = 0; 205. croom->lx = lowx; 206. croom->hx = hix; 207. croom->ly = lowy; 208. croom->hy = hiy; 209. croom->rtype = OROOM; 210. croom->doorct = 0; 211. /* if we're not making a vault, doorindex will still be 0 212. * if we are, we'll have problems adding niches to the previous room 213. * unless fdoor is at least doorindex 214. */ 215. croom->fdoor = doorindex; 216. 217. for(x = lowx-1; x <= hix+1; x++) 218. for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 219. levl[x][y].typ = HWALL; 220. levl[x][y].scrsym = HWALL_SYM; 221. } 222. for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 223. for(y = lowy; y <= hiy; y++) { 224. levl[x][y].typ = VWALL; 225. levl[x][y].scrsym = VWALL_SYM; 226. } 227. for(x = lowx; x <= hix; x++) 228. for(y = lowy; y <= hiy; y++) { 229. levl[x][y].typ = ROOM; 230. levl[x][y].scrsym = ROOM_SYM; 231. } 232. levl[lowx-1][lowy-1].typ = TLCORNER; 233. levl[hix+1][lowy-1].typ = TRCORNER; 234. levl[lowx-1][hiy+1].typ = BLCORNER; 235. levl[hix+1][hiy+1].typ = BRCORNER; 236. levl[lowx-1][lowy-1].scrsym = TLCORN_SYM; 237. levl[hix+1][lowy-1].scrsym = TRCORN_SYM; 238. levl[lowx-1][hiy+1].scrsym = BLCORN_SYM; 239. levl[hix+1][hiy+1].scrsym = BRCORN_SYM; 240. 241. smeq[nroom] = nroom; 242. croom++; 243. croom->hx = -1; 244. nroom++; 245. return(1); 246. } 247. 248. static int 249. makerooms() { 250. register struct rectangle *rsp; 251. register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy; 252. int tryct = 0, xlim, ylim; 253. 254. /* init */ 255. xlim = XLIM + secret; 256. ylim = YLIM + secret; 257. if(nroom == 0) { 258. rsp = rs; 259. rsp->rlx = rsp->rly = 0; 260. rsp->rhx = COLNO-1; 261. rsp->rhy = ROWNO-1; 262. rsmax = 1; 263. } 264. rscnt = rsmax; 265. 266. /* make rooms until satisfied */ 267. while(rscnt > 0 && nroom < MAXNROFROOMS-1) { 268. if(!secret && nroom > (MAXNROFROOMS/4) && 269. !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom))) 270. return 0; 271. 272. /* pick a rectangle */ 273. rsp = &rs[rn2(rscnt)]; 274. hx = rsp->rhx; 275. hy = rsp->rhy; 276. lx = rsp->rlx; 277. ly = rsp->rly; 278. 279. /* find size of room */ 280. if(secret) 281. dx = dy = 1; 282. else { 283. dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8); 284. dy = 2 + rn2(4); 285. if(dx*dy > 50) 286. dy = 50/dx; 287. } 288. 289. /* look whether our room will fit */ 290. if(hx-lx < dx + (dx>>1) + 2*xlim || 291. hy-ly < dy + dy/3 + 2*ylim) { 292. /* no, too small */ 293. /* maybe we throw this area out */ 294. if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) { 295. rscnt--; 296. rs[rsmax] = *rsp; 297. *rsp = rs[rscnt]; 298. rs[rscnt] = rs[rsmax]; 299. tryct = 0; 300. } else 301. tryct++; 302. continue; 303. } 304. 305. lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1); 306. lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1); 307. hix = lowx + dx; 308. hiy = lowy + dy; 309. 310. if(maker(lowx, dx, lowy, dy, FALSE)) { 311. if(secret) return(1); 312. addrs(lowx-1, lowy-1, hix+1, hiy+1); 313. tryct = 0; 314. } else 315. if(tryct++ > 100) 316. break; 317. } 318. return(0); /* failed to make vault - very strange */ 319. } 320. 321. static void 322. join(a,b) 323. register int a, b; 324. { 325. coord cc,tt; 326. register int tx, ty, xx, yy; 327. register struct rm *crm; 328. register struct mkroom *croom, *troom; 329. register int dx, dy, dix, diy, cct; 330. 331. croom = &rooms[a]; 332. troom = &rooms[b]; 333. 334. /* find positions cc and tt for doors in croom and troom 335. and direction for a corridor between them */ 336. 337. if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; 338. if(troom->lx > croom->hx) { 339. dx = 1; 340. dy = 0; 341. xx = croom->hx+1; 342. tx = troom->lx-1; 343. finddpos(&cc, xx, croom->ly, xx, croom->hy); 344. finddpos(&tt, tx, troom->ly, tx, troom->hy); 345. } else if(troom->hy < croom->ly) { 346. dy = -1; 347. dx = 0; 348. yy = croom->ly-1; 349. finddpos(&cc, croom->lx, yy, croom->hx, yy); 350. ty = troom->hy+1; 351. finddpos(&tt, troom->lx, ty, troom->hx, ty); 352. } else if(troom->hx < croom->lx) { 353. dx = -1; 354. dy = 0; 355. xx = croom->lx-1; 356. tx = troom->hx+1; 357. finddpos(&cc, xx, croom->ly, xx, croom->hy); 358. finddpos(&tt, tx, troom->ly, tx, troom->hy); 359. } else { 360. dy = 1; 361. dx = 0; 362. yy = croom->hy+1; 363. ty = troom->ly-1; 364. finddpos(&cc, croom->lx, yy, croom->hx, yy); 365. finddpos(&tt, troom->lx, ty, troom->hx, ty); 366. } 367. xx = cc.x; 368. yy = cc.y; 369. tx = tt.x - dx; 370. ty = tt.y - dy; 371. if(nxcor && levl[xx+dx][yy+dy].typ) 372. return; 373. dodoor(xx,yy,croom); 374. 375. cct = 0; 376. while(xx != tx || yy != ty) { 377. xx += dx; 378. yy += dy; 379. 380. /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ 381. if(cct++ > 500 || (nxcor && !rn2(35))) 382. return; 383. 384. if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) 385. return; /* impossible */ 386. 387. crm = &levl[xx][yy]; 388. if(!(crm->typ)) { 389. if(rn2(100)) { 390. crm->typ = CORR; 391. crm->scrsym = CORR_SYM; 392. if(nxcor && !rn2(50)) 393. (void) mksobj_at(BOULDER, xx, yy); 394. } else { 395. crm->typ = SCORR; 396. crm->scrsym = STONE_SYM; 397. } 398. } else 399. if(crm->typ != CORR && crm->typ != SCORR) { 400. /* strange ... */ 401. return; 402. } 403. 404. /* find next corridor position */ 405. dix = abs(xx-tx); 406. diy = abs(yy-ty); 407. 408. /* do we have to change direction ? */ 409. if(dy && dix > diy) { 410. register int ddx = (xx > tx) ? -1 : 1; 411. 412. crm = &levl[xx+ddx][yy]; 413. if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 414. dx = ddx; 415. dy = 0; 416. continue; 417. } 418. } else if(dx && diy > dix) { 419. register int ddy = (yy > ty) ? -1 : 1; 420. 421. crm = &levl[xx][yy+ddy]; 422. if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 423. dy = ddy; 424. dx = 0; 425. continue; 426. } 427. } 428. 429. /* continue straight on? */ 430. crm = &levl[xx+dx][yy+dy]; 431. if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 432. continue; 433. 434. /* no, what must we do now?? */ 435. if(dx) { 436. dx = 0; 437. dy = (ty < yy) ? -1 : 1; 438. crm = &levl[xx+dx][yy+dy]; 439. if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 440. continue; 441. dy = -dy; 442. continue; 443. } else { 444. dy = 0; 445. dx = (tx < xx) ? -1 : 1; 446. crm = &levl[xx+dx][yy+dy]; 447. if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 448. continue; 449. dx = -dx; 450. continue; 451. } 452. } 453. 454. /* we succeeded in digging the corridor */ 455. dodoor(tt.x, tt.y, troom); 456. 457. if(smeq[a] < smeq[b]) 458. smeq[b] = smeq[a]; 459. else 460. smeq[a] = smeq[b]; 461. } 462. 463. static void 464. makecorridors() { 465. register int a, b; 466. 467. nxcor = 0; 468. for(a = 0; a < nroom-1; a++) 469. join(a, a+1); 470. for(a = 0; a < nroom-2; a++) 471. if(smeq[a] != smeq[a+2]) 472. join(a, a+2); 473. for(a = 0; a < nroom; a++) 474. for(b = 0; b < nroom; b++) 475. if(smeq[a] != smeq[b]) 476. join(a, b); 477. if(nroom > 2) 478. for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) { 479. a = rn2(nroom); 480. b = rn2(nroom-2); 481. if(b >= a) b += 2; 482. join(a, b); 483. } 484. } 485. 486. static void 487. dosdoor(x,y,aroom,type) 488. register int x, y; 489. register struct mkroom *aroom; 490. register int type; 491. { 492. register struct mkroom *broom; 493. register int tmp; 494. boolean shdoor = in_shop(x, y); 495. 496. if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */ 497. type = DOOR; 498. levl[x][y].typ = type; 499. if(type == DOOR) { 500. levl[x][y].scrsym = DOOR_SYM; 501. if(!rn2(3)) { /* is it a locked door, closed, or a doorway? */ 502. if(!rn2(5)) 503. levl[x][y].doormask = D_ISOPEN; 504. else if(!rn2(4)) 505. levl[x][y].doormask = D_LOCKED; 506. else 507. levl[x][y].doormask = D_CLOSED; 508. 509. if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25)) 510. levl[x][y].doormask |= D_TRAPPED; 511. } else { 512. if(shdoor) levl[x][y].doormask = D_ISOPEN; 513. else levl[x][y].doormask = D_NODOOR; 514. } 515. } else { /* SDOOR */ 516. if(shdoor || !rn2(5)) levl[x][y].doormask = D_LOCKED; 517. else levl[x][y].doormask = D_CLOSED; 518. 519. if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED; 520. } 521. aroom->doorct++; 522. broom = aroom+1; 523. if(broom->hx < 0) tmp = doorindex; else 524. for(tmp = doorindex; tmp > broom->fdoor; tmp--) 525. doors[tmp] = doors[tmp-1]; 526. doorindex++; 527. doors[tmp].x = x; 528. doors[tmp].y = y; 529. for( ; broom->hx >= 0; broom++) broom->fdoor++; 530. } 531. 532. static boolean 533. place_niche(aroom,dy,xx,yy) 534. register struct mkroom *aroom; 535. int *dy, *xx, *yy; 536. { 537. coord dd; 538. 539. if(rn2(2)) { 540. *dy = 1; 541. finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1); 542. } else { 543. *dy = -1; 544. finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1); 545. } 546. *xx = dd.x; 547. *yy = dd.y; 548. return(levl[*xx][(*yy)+(*dy)].typ == STONE); 549. } 550. 551. #ifdef ORACLE 552. boolean 553. place_oracle(aroom,dy,xx,yy) 554. register struct mkroom *aroom; 555. int *dy, *xx, *yy; 556. { 557. if(!place_niche(aroom,dy,xx,yy)) return FALSE; 558. 559. dosdoor(*xx,*yy,aroom,DOOR); 560. levl[*xx][*yy].doormask = D_NODOOR; 561. return TRUE; 562. } 563. #endif 564. 565. /* there should be one of these per trap */ 566. const char *engravings[] = { "", "", "", "", "", "", 567. "?la? ?as ?er?", "ad ae?ar um", 568. "", "", "", "" ,"" 569. , "", "ad ae?ar um" 570. #ifdef SPELLS 571. ,"" 572. #endif 573. ,"" 574. #ifdef POLYSELF 575. ,"" 576. #endif 577. ,"" 578. }; 579. 580. static void 581. makeniche(trap_type) 582. int trap_type; 583. { 584. register struct mkroom *aroom; 585. register struct rm *rm; 586. register int vct = 8; 587. int dy, xx, yy; 588. register struct trap *ttmp; 589. 590. if(doorindex < DOORMAX) 591. while(vct--) { 592. aroom = &rooms[rn2(nroom)]; 593. if(aroom->rtype != OROOM) continue; /* not an ordinary room */ 594. if(aroom->doorct == 1 && rn2(5)) continue; 595. if(!place_niche(aroom,&dy,&xx,&yy)) continue; 596. 597. rm = &levl[xx][yy+dy]; 598. if(trap_type || !rn2(4)) { 599. 600. rm->typ = SCORR; 601. rm->scrsym = STONE_SYM; 602. if(trap_type) { 603. ttmp = maketrap(xx, yy+dy, trap_type); 604. ttmp->once = 1; 605. if (strlen(engravings[trap_type]) > 0) 606. make_engr_at(xx, yy-dy, engravings[trap_type]); 607. } 608. dosdoor(xx, yy, aroom, SDOOR); 609. } else { 610. rm->typ = CORR; 611. rm->scrsym = CORR_SYM; 612. if(rn2(7)) 613. dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); 614. else { 615. (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy); 616. if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy); 617. } 618. } 619. return; 620. } 621. } 622. 623. static void 624. make_niches() 625. { 626. register int ct = rnd((nroom>>1) + 1); 627. boolean ltptr = TRUE, 628. vamp = TRUE; 629. 630. while(ct--) { 631. 632. if(dlevel > 15 && !rn2(6) && ltptr) { 633. 634. ltptr = FALSE; 635. makeniche(LEVEL_TELEP); 636. } else if (dlevel > 5 && dlevel < 25 637. && !rn2(6) && vamp) { 638. 639. vamp = FALSE; 640. makeniche(TRAPDOOR); 641. } else makeniche(NO_TRAP); 642. } 643. } 644. 645. static void 646. makebigroom() 647. { 648. register int x,y,n; 649. register struct mkroom *croom; 650. register struct monst *tmonst; 651. 652. /* make biggest possible room; make sure it's lit */ 653. (void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE); 654. croom = &rooms[0]; 655. 656. /* add extra monsters and goodies */ 657. n = 10 + rn2(15); 658. while (n--) { 659. x = somex(croom); 660. y = somey(croom); 661. tmonst = makemon((struct permonst *) 0,x,y); 662. if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER]) 663. (void) maketrap(x,y,WEB); 664. if (tmonst && rn2(2)) 665. tmonst->msleep = 1; 666. } 667. n = 6 + rn2(10); 668. while (n--) 669. (void) mkobj_at(0,somex(croom),somey(croom)); 670. } 671. 672. static void 673. makevtele() 674. { 675. makeniche(TELEP_TRAP); 676. } 677. 678. #define rntwixt(L1,L2) rn1((L2)-(L1),L1) 679. 680. static void 681. init_levels() 682. { 683. #if defined(STRONGHOLD) && defined(MUSIC) 684. register int x; 685. #endif 686. 687. #ifdef LINT /* handle constant in conditional context */ 688. medusa_level = 0; 689. #else 690. medusa_level = rn1(3, HELLLEVEL - 5); 691. #endif /* LINT */ 692. #ifdef STRONGHOLD 693. stronghold_level = rn1(5, medusa_level)+1; 694. # ifdef MUSIC 695. for (x=0; x<5; x++) 696. tune[x] = 'A' + rn2(7); 697. tune[5] = 0; 698. # endif 699. /* The tower will be on 3 levels */ 700. tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1; 701. /* We don't want the wizard in Vlad's tower */ 702. do 703. wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1; 704. while (wiz_level >= tower_level && wiz_level <= tower_level + 2); 705. #else 706. wiz_level = rntwixt(medusa_level, MAXLEVEL)+1; 707. #endif /* STRONGHOLD /**/ 708. #ifdef WIZARD 709. if (!rn2(15) || wizard) 710. #else 711. if (!rn2(15)) 712. #endif 713. /* between the middle of the dungeon and the medusa level */ 714. bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level); 715. #ifdef REINCARNATION 716. # ifdef WIZARD 717. if (!rn2(3) || wizard) 718. # else 719. if (!rn2(3)) 720. # endif 721. rogue_level = rn1(5,10); 722. #endif 723. #ifdef ORACLE 724. oracle_level = rn1(4,5); 725. #endif 726. } 727. 728. #undef rntwixt 729. 730. static void 731. makelevel() { 732. register struct mkroom *croom, *troom; 733. register unsigned int tryct; 734. register int x,y; 735. struct monst *tmonst; /* always put a web with a spider */ 736. 737. nroom = 0; 738. doorindex = 0; 739. rooms[0].hx = -1; /* in case we are in a maze */ 740. 741. for(x=0; x 742. levl[x][y] = zerorm; 743. 744. oinit(); /* assign level dependent obj probabilities */ 745. fountsound = 0; 746. sinksound = 0; 747. 748. if (wiz_level == 0) 749. init_levels(); 750. if ( 751. #ifndef STRONGHOLD 752. Inhell 753. #else 754. dlevel >= stronghold_level || dlevel < 0 755. #endif 756. || (dlevel > medusa_level && rn2(5)) 757. ) { 758. makemaz(); 759. return; 760. } 761. 762. /* construct the rooms */ 763. nroom = 0; 764. secret = FALSE; 765. 766. #ifdef REINCARNATION 767. if (dlevel == rogue_level) { 768. makeroguerooms(); 769. makerogueghost(); 770. } else 771. #endif 772. if (dlevel == bigroom_level) 773. makebigroom(); 774. else 775. (void) makerooms(); 776. 777. /* construct stairs (up and down in different rooms if possible) */ 778. croom = &rooms[rn2(nroom)]; 779. xdnstair = somex(croom); 780. ydnstair = somey(croom); 781. levl[xdnstair][ydnstair].scrsym = DN_SYM; 782. levl[xdnstair][ydnstair].typ = STAIRS; 783. #ifdef MEDUSA 784. if (dlevel == medusa_level) { 785. struct monst *mtmp; 786. 787. if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair)) 788. mtmp->msleep = 1; 789. for (tryct = rn1(1,3); tryct; tryct--) { 790. x = somex(croom); y = somey(croom); 791. if (goodpos(x,y)) 792. (void) mk_tt_statue(x, y); 793. } 794. } 795. #endif 796. if(nroom > 1) { 797. troom = croom; 798. croom = &rooms[rn2(nroom-1)]; 799. if(croom >= troom) croom++; 800. } 801. xupstair = somex(croom); /* %% < and > might be in the same place */ 802. yupstair = somey(croom); 803. levl[xupstair][yupstair].scrsym = UP_SYM; 804. levl[xupstair][yupstair].typ = STAIRS; 805. #ifdef STRONGHOLD 806. xdnladder = ydnladder = xupladder = yupladder = 0; 807. #endif 808. is_maze_lev = FALSE; 809. 810. #ifdef SYSV 811. qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp); 812. #else 813. qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp); 814. #endif 815. #ifdef REINCARNATION 816. if (dlevel == rogue_level) { 817. You("feel as though you were here in a previous lifetime."); 818. return; 819. } 820. #endif 821. makecorridors(); 822. make_niches(); 823. 824. /* make a secret treasure vault, not connected to the rest */ 825. if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) { 826. 827. troom = &rooms[nroom]; 828. secret = TRUE; 829. if(makerooms()) { 830. troom->rtype = VAULT; /* treasure vault */ 831. for(x = troom->lx; x <= troom->hx; x++) 832. for(y = troom->ly; y <= troom->hy; y++) 833. mkgold((long)(rnd(dlevel*100) + 50), x, y); 834. if(!rn2(3)) 835. makevtele(); 836. } 837. } 838. 839. #ifdef WIZARD 840. if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else 841. #endif 842. #ifdef ORACLE 843. if(dlevel == oracle_level) mkroom(DELPHI); 844. /* It is possible that we find no good place to set up Delphi. 845. * It is also possible to get more than one Delphi using bones levels. 846. * The first is not a problem; the second is a minor nuisance. 847. */ 848. else 849. #endif 850. if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE); 851. else 852. #ifdef THRONES 853. if(dlevel > 4 && !rn2(6)) mkroom(COURT); 854. else 855. #endif 856. if(dlevel > 6 && !rn2(7)) mkroom(ZOO); 857. else 858. #ifdef ALTARS 859. if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE); 860. else 861. #endif 862. if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD)) 863. mkroom(BEEHIVE); 864. else 865. if(dlevel > 11 && !rn2(6)) mkroom(MORGUE); 866. else 867. #ifdef ARMY 868. if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD)) 869. mkroom(BARRACKS); 870. else 871. #endif 872. if(dlevel > 18 && !rn2(6)) mkroom(SWAMP); 873. 874. 875. /* for each room: put things inside */ 876. for(croom = rooms; croom->hx > 0; croom++) { 877. register boolean boxinlev = FALSE; 878. 879. if(croom->rtype != OROOM) continue; 880. 881. /* put a sleeping monster inside */ 882. /* Note: monster may be on the stairs. This cannot be 883. avoided: maybe the player fell through a trapdoor 884. while a monster was on the stairs. Conclusion: 885. we have to check for monsters on the stairs anyway. */ 886. 887. if(u.uhave_amulet || !rn2(3)) { 888. x = somex(croom); y = somey(croom); 889. #ifdef REINCARNATION 890. if (dlevel == rogue_level) 891. tmonst = makemon(roguemon(), x, y); 892. else 893. #endif 894. tmonst = makemon((struct permonst *) 0, x,y); 895. if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]) 896. (void) maketrap (x,y,WEB); 897. } 898. /* put traps and mimics inside */ 899. goldseen = FALSE; 900. while(!rn2(8-(dlevel/6))) mktrap(0,0,croom); 901. if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom)); 902. #ifdef REINCARNATION 903. if (dlevel == rogue_level) goto skip_nonrogue; 904. #endif 905. #ifdef FOUNTAINS 906. if(!rn2(10)) mkfount(0,croom); 907. #endif 908. #ifdef SINKS 909. if(!rn2(60)) mksink(croom); 910. #endif 911. #ifdef ALTARS 912. if(!rn2(60)) mkaltar(croom); 913. #endif 914. /* put statues inside */ 915. #ifdef MEDUSA 916. if(!rn2(dlevel == medusa_level ? 1 : 20)) { 917. if (!rn2(dlevel == medusa_level ? 2 : 50)) 918. (void) mk_tt_statue(somex(croom), somey(croom)); 919. else { 920. struct obj *otmp = 921. mkstatue((struct permonst *)0, 922. somex(croom), somey(croom)); 923. if (dlevel == medusa_level && otmp) 924. otmp->spe = 0; 925. /* Medusa statues don't contain books */ 926. } 927. } 928. #else 929. if(!rn2(20)) 930. (void) mkstatue((struct permonst *)0, 931. somex(croom), somey(croom)); 932. #endif 933. 934. /* put box/chest inside */ 935. if(!rn2(20) && !boxinlev) { 936. 937. boxinlev = TRUE; 938. (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, 939. somex(croom), somey(croom)); 940. } 941. 942. #ifdef REINCARNATION 943. skip_nonrogue: 944. #endif 945. if(!rn2(3)) { 946. (void) mkobj_at(0, somex(croom), somey(croom)); 947. tryct = 0; 948. while(!rn2(5)) { 949. if(++tryct > 100){ 950. Printf("tryct overflow4
"); 951. break; 952. } 953. (void) mkobj_at(0, somex(croom), somey(croom)); 954. } 955. } 956. } 957. } 958. 959. void 960. mklev() 961. { 962. if(getbones()) return; 963. 964. in_mklev = TRUE; 965. makelevel(); 966. bound_digging(); 967. in_mklev = FALSE; 968. } 969. 970. static boolean 971. bydoor(x, y) 972. register xchar x, y; 973. { 974. register boolean tmp1, tmp2; 975. 976. /* break up large expression to help some compilers */ 977. tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR || 978. IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR); 979. tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR || 980. IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR); 981. return(tmp1 || tmp2); 982. } 983. 984. /* see whether it is allowable to create a door at [x,y] */ 985. int 986. okdoor(x,y) 987. register xchar x, y; 988. { 989. register boolean near_door = bydoor(x, y); 990. 991. return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) && 992. doorindex < DOORMAX && !near_door); 993. } 994. 995. void 996. dodoor(x,y,aroom) 997. register int x, y; 998. register struct mkroom *aroom; 999. { 1000. if(doorindex >= DOORMAX) { 1001. impossible("DOORMAX exceeded?"); 1002. return; 1003. } 1004. if(!okdoor(x,y) && nxcor) 1005. return; 1006. dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); 1007. } 1008. 1009. static boolean 1010. occupied(x, y) 1011. register xchar x, y; 1012. { 1013. return(t_at(x, y) || levl[x][y].typ == STAIRS 1014. #ifdef FOUNTAINS 1015. || IS_FOUNTAIN(levl[x][y].typ) 1016. #endif 1017. #ifdef THRONES 1018. || IS_THRONE(levl[x][y].typ) 1019. #endif 1020. #ifdef SINKS 1021. || IS_SINK(levl[x][y].typ) 1022. #endif 1023. #ifdef ALTARS 1024. || levl[x][y].typ == ALTAR 1025. #endif 1026. ); 1027. } 1028. 1029. /* make a trap somewhere (in croom if mazeflag = 0) */ 1030. void 1031. mktrap(num, mazeflag, croom) 1032. register int num, mazeflag; 1033. register struct mkroom *croom; 1034. { 1035. register struct trap *ttmp; 1036. register int kind,nomonst,nomimic,nospider, 1037. #ifdef POLYSELF 1038. nopoly, 1039. #endif 1040. nospikes, nolevltp, 1041. nolandmine, 1042. tryct = 0; 1043. 1044. xchar mx,my; 1045. 1046. if(!num || num >= TRAPNUM) { 1047. nomonst = (dlevel < 4) ? 1 : 0; 1048. nolevltp = (dlevel < 5) ? 1 : 0; 1049. nospikes = (dlevel < 6) ? 1 : 0; 1050. nospider = (dlevel < 7) ? 1 : 0; 1051. #ifdef POLYSELF 1052. nopoly = (dlevel < 6) ? 1 : 0; 1053. #endif 1054. nolandmine = (dlevel < 5) ? 1 : 0; 1055. nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; 1056. if((mons[PM_SMALL_MIMIC].geno & G_GENOD) && 1057. (mons[PM_LARGE_MIMIC].geno & G_GENOD) && 1058. (mons[PM_GIANT_MIMIC].geno & G_GENOD)) 1059. nomimic = 1; 1060. if(mons[PM_GIANT_SPIDER].geno & G_GENOD) 1061. nospider = 1; 1062. 1063. do { 1064. #ifdef REINCARNATION 1065. if (dlevel==rogue_level) { 1066. switch(rn2(7)) { 1067. case 0: kind = BEAR_TRAP; break; 1068. case 1: kind = ARROW_TRAP; break; 1069. case 2: kind = DART_TRAP; break; 1070. case 3: kind = TRAPDOOR; break; 1071. case 4: kind = PIT; break; 1072. case 5: kind = SLP_GAS_TRAP; break; 1073. case 6: kind = RUST_TRAP; break; 1074. } 1075. } else 1076. #endif 1077. kind = rnd(TRAPNUM-1); 1078. if((kind == MONST_TRAP && (nomonst && nomimic)) 1079. || ((kind == WEB) && nospider) 1080. || (kind == SPIKED_PIT && nospikes) 1081. || (kind == LEVEL_TELEP && nolevltp) 1082. #ifdef POLYSELF 1083. || (kind == POLY_TRAP && nopoly) 1084. #endif 1085. || (kind == LANDMINE && nolandmine) 1086. ) kind = NO_TRAP; 1087. } while(kind == NO_TRAP); 1088. } else kind = num; 1089. 1090. if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) { 1091. register struct monst *mtmp; 1092. 1093. do { 1094. if(++tryct > 200) return; 1095. /* note: fakedoor maybe on actual door */ 1096. if(rn2(2)){ 1097. if(rn2(2)) mx = croom->hx+1; 1098. else mx = croom->lx-1; 1099. my = somey(croom); 1100. } else { 1101. if(rn2(2)) my = croom->hy+1; 1102. else my = croom->ly-1; 1103. mx = somex(croom); 1104. } 1105. } while(levl[mx][my].mmask); 1106. 1107. if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) { 1108. mtmp->mimic = 1; 1109. mtmp->mappearance = DOOR_SYM; 1110. } 1111. return; 1112. } 1113. 1114. do { 1115. if(++tryct > 200) 1116. return; 1117. if(mazeflag){ 1118. coord mm; 1119. mazexy(&mm); 1120. mx = mm.x; 1121. my = mm.y; 1122. } else { 1123. mx = somex(croom); 1124. my = somey(croom); 1125. } 1126. } while(occupied(mx, my)); 1127. 1128. ttmp = maketrap(mx, my, kind); 1129. if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my); 1130. if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP) 1131. ttmp->tseen = 1; 1132. } 1133. 1134. #ifdef FOUNTAINS 1135. void 1136. mkfount(mazeflag,croom) 1137. register struct mkroom *croom; 1138. register int mazeflag; 1139. { 1140. register xchar mx,my; 1141. register int tryct = 0; 1142. 1143. do { 1144. if(++tryct > 200) return; 1145. if(mazeflag) { 1146. coord mm; 1147. mazexy(&mm); 1148. mx = mm.x; 1149. my = mm.y; 1150. } else { 1151. mx = somex(croom); 1152. my = somey(croom); 1153. } 1154. } while(occupied(mx, my) || bydoor(mx, my)); 1155. 1156. /* Put a fountain at mx, my */ 1157. levl[mx][my].typ = FOUNTAIN; 1158. levl[mx][my].scrsym = FOUNTAIN_SYM; 1159. 1160. fountsound++; 1161. } 1162. #endif /* FOUNTAINS /**/ 1163. 1164. #ifdef SINKS 1165. static void 1166. mksink(croom) 1167. register struct mkroom *croom; 1168. { 1169. register xchar mx,my; 1170. register int tryct = 0; 1171. 1172. do { 1173. if(++tryct > 200) return; 1174. mx = somex(croom); 1175. my = somey(croom); 1176. } while(occupied(mx, my) || bydoor(mx, my)); 1177. 1178. /* Put a sink at mx, my */ 1179. levl[mx][my].typ = SINK; 1180. levl[mx][my].scrsym = SINK_SYM; 1181. 1182. sinksound++; 1183. } 1184. #endif /* SINKS /**/ 1185. 1186. 1187. #ifdef ALTARS 1188. static void 1189. mkaltar(croom) 1190. register struct mkroom *croom; 1191. { 1192. register xchar mx,my; 1193. register int tryct = 0; 1194. 1195. if(croom->rtype != OROOM) return; 1196. 1197. do { 1198. if(++tryct > 200) return; 1199. mx = somex(croom); 1200. my = somey(croom); 1201. } while(occupied(mx, my) || bydoor(mx, my)); 1202. 1203. /* Put an altar at mx, my */ 1204. levl[mx][my].typ = ALTAR; 1205. levl[mx][my].scrsym = ALTAR_SYM; 1206. /* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */ 1207. levl[mx][my].altarmask = rn2((int)A_LAW+1); 1208. } 1209. #endif /* ALTARS /**/
|