Difference between revisions of "Source:NetHack 3.0.0/mklev.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 3.0.0/mklev.c moved to Source:NetHack 3.0.0/mklev.c: Robot: moved page) |
(No difference)
|
Latest revision as of 04:54, 4 March 2008
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
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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<COLNO; x++) for(y=0; y<ROWNO; y++) 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\n"); 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 /**/