Source:SLASH'EM 0.0.7E7F2/mkroom.c
Jump to navigation
Jump to search
Below is the full text to mkroom.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[Source:SLASH'EM 0.0.7E7F2/mkroom.c#line123]], for example.
Source code for vanilla NetHack is at 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: @(#)mkroom.c 3.4 2001/09/06 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* 6. * Entry points: 7. * mkroom() -- make and stock a room of a given type 8. * nexttodoor() -- return TRUE if adjacent to a door 9. * has_dnstairs() -- return TRUE if given room has a down staircase 10. * has_upstairs() -- return TRUE if given room has an up staircase 11. * courtmon() -- generate a court monster 12. * save_rooms() -- save rooms into file fd 13. * rest_rooms() -- restore rooms from file fd 14. */ 15. 16. #include "hack.h" 17. 18. #ifdef OVLB 19. STATIC_DCL boolean FDECL(isbig, (struct mkroom *)); 20. STATIC_DCL struct mkroom * FDECL(pick_room,(BOOLEAN_P)); 21. STATIC_DCL void NDECL(mkshop), FDECL(mkzoo,(int)), NDECL(mkswamp); 22. STATIC_DCL void NDECL(mktemple); 23. STATIC_DCL coord * FDECL(shrine_pos, (int)); 24. STATIC_DCL struct permonst * NDECL(morguemon); 25. STATIC_DCL struct permonst * NDECL(squadmon); 26. STATIC_DCL struct permonst * NDECL(fungus); 27. STATIC_DCL void FDECL(save_room, (int,struct mkroom *)); 28. STATIC_DCL void FDECL(rest_room, (int,struct mkroom *)); 29. #endif /* OVLB */ 30. 31. #define sq(x) ((x)*(x)) 32. 33. extern const struct shclass shtypes[]; /* defined in shknam.c */ 34. 35. #ifdef OVLB 36. 37. STATIC_OVL boolean 38. isbig(sroom) 39. register struct mkroom *sroom; 40. { 41. register int area = (sroom->hx - sroom->lx + 1) 42. * (sroom->hy - sroom->ly + 1); 43. return((boolean)( area > 20 )); 44. } 45. 46. void 47. mkroom(roomtype) 48. /* make and stock a room of a given type */ 49. int roomtype; 50. { 51. if (roomtype >= SHOPBASE) 52. mkshop(); /* someday, we should be able to specify shop type */ 53. else switch(roomtype) { 54. case COURT: mkzoo(COURT); break; 55. case ZOO: mkzoo(ZOO); break; 56. case BEEHIVE: mkzoo(BEEHIVE); break; 57. case MORGUE: mkzoo(MORGUE); break; 58. case BARRACKS: mkzoo(BARRACKS); break; 59. case REALZOO: mkzoo(REALZOO); break; 60. case BADFOODSHOP: mkzoo(BADFOODSHOP); break; 61. case DRAGONLAIR: mkzoo(DRAGONLAIR); break; 62. case GIANTCOURT: mkzoo(GIANTCOURT); break; 63. case SWAMP: mkswamp(); break; 64. case TEMPLE: mktemple(); break; 65. case LEPREHALL: mkzoo(LEPREHALL); break; 66. case COCKNEST: mkzoo(COCKNEST); break; 67. case ANTHOLE: mkzoo(ANTHOLE); break; 68. case LEMUREPIT: mkzoo(LEMUREPIT); break; 69. case MIGOHIVE: mkzoo(MIGOHIVE); break; 70. case FUNGUSFARM: mkzoo(FUNGUSFARM); break; 71. default: impossible("Tried to make a room of type %d.", roomtype); 72. } 73. } 74. 75. STATIC_OVL void 76. mkshop() 77. { 78. register struct mkroom *sroom; 79. int i = -1, j; 80. #ifdef WIZARD 81. char *ep = (char *)0; /* (init == lint suppression) */ 82. 83. /* first determine shoptype */ 84. if(wizard){ 85. #ifndef MAC 86. ep = nh_getenv("SHOPTYPE"); 87. if(ep){ 88. if(*ep == 'z' || *ep == 'Z'){ 89. mkzoo(ZOO); 90. return; 91. } 92. if(*ep == 'm' || *ep == 'M'){ 93. mkzoo(MORGUE); 94. return; 95. } 96. if(*ep == 'b' || *ep == 'B'){ 97. mkzoo(BEEHIVE); 98. return; 99. } 100. if (*ep == 'p' || *ep == 'P') { 101. mkzoo(LEMUREPIT); 102. return; 103. } 104. if (*ep == 'i' || *ep == 'I') { 105. mkzoo(MIGOHIVE); 106. return; 107. } 108. if (*ep == 'f' || *ep == 'F') { 109. mkzoo(FUNGUSFARM); 110. return; 111. } 112. if(*ep == 't' || *ep == 'T' || *ep == '\\'){ 113. mkzoo(COURT); 114. return; 115. } 116. if(*ep == 's' || *ep == 'S'){ 117. mkzoo(BARRACKS); 118. return; 119. } 120. if(*ep == 'a' || *ep == 'A'){ 121. mkzoo(ANTHOLE); 122. return; 123. } 124. if(*ep == 'c' || *ep == 'C'){ 125. mkzoo(COCKNEST); 126. return; 127. } 128. if(*ep == 'l' || *ep == 'L'){ 129. mkzoo(LEPREHALL); 130. return; 131. } 132. if(*ep == '_'){ 133. mktemple(); 134. return; 135. } 136. if(*ep == '}'){ 137. mkswamp(); 138. return; 139. } 140. j = -1; 141. for(i=0; shtypes[i].name; i++) 142. if(*ep == def_oc_syms[(int)shtypes[i].symb]) { 143. if (j < 0) j = i; 144. if (!strcmp(ep + 1, shtypes[i].name)) 145. break; 146. } 147. if(*ep == 'g' || *ep == 'G') 148. i = 0; 149. else 150. i = j; 151. } 152. #endif 153. } 154. #endif 155. for(sroom = &rooms[0]; ; sroom++){ 156. if(sroom->hx < 0) return; 157. if(sroom - rooms >= nroom) { 158. pline("rooms not closed by -1?"); 159. return; 160. } 161. if(sroom->rtype != OROOM) continue; 162. if(has_dnstairs(sroom) || has_upstairs(sroom)) 163. continue; 164. if( 165. #ifdef WIZARD 166. (wizard && ep && sroom->doorct != 0) || 167. #endif 168. sroom->doorct == 1) break; 169. } 170. if (!sroom->rlit) { 171. int x, y; 172. 173. for(x = sroom->lx - 1; x <= sroom->hx + 1; x++) 174. for(y = sroom->ly - 1; y <= sroom->hy + 1; y++) 175. levl[x][y].lit = 1; 176. sroom->rlit = 1; 177. } 178. 179. if(i < 0) { /* shoptype not yet determined */ 180. /* pick a shop type at random */ 181. for (j = rnd(100), i = 0; (j -= shtypes[i].prob) > 0; i++) 182. continue; 183. 184. /* big rooms cannot be wand or book shops, 185. * - so make them general stores 186. */ 187. if(isbig(sroom) && (shtypes[i].symb == WAND_CLASS 188. || shtypes[i].symb == SPBOOK_CLASS)) i = 0; 189. } 190. sroom->rtype = SHOPBASE + i; 191. 192. /* set room bits before stocking the shop */ 193. #ifdef SPECIALIZATION 194. topologize(sroom, FALSE); /* doesn't matter - this is a special room */ 195. #else 196. topologize(sroom); 197. #endif 198. 199. /* stock the room with a shopkeeper and artifacts */ 200. stock_room(i, sroom); 201. } 202. 203. STATIC_OVL struct mkroom * 204. pick_room(strict) 205. register boolean strict; 206. /* pick an unused room, preferably with only one door */ 207. { 208. register struct mkroom *sroom; 209. register int i = nroom; 210. 211. for(sroom = &rooms[rn2(nroom)]; i--; sroom++) { 212. if(sroom == &rooms[nroom]) 213. sroom = &rooms[0]; 214. if(sroom->hx < 0) 215. return (struct mkroom *)0; 216. if(sroom->rtype != OROOM) continue; 217. if(!strict) { 218. if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 219. continue; 220. } else if(has_upstairs(sroom) || has_dnstairs(sroom)) 221. continue; 222. if(sroom->doorct == 1 || (!rn2(5) && !strict) 223. #ifdef WIZARD 224. || (wizard && !strict) 225. #endif 226. ) 227. return sroom; 228. } 229. return (struct mkroom *)0; 230. } 231. 232. STATIC_OVL void 233. mkzoo(type) 234. int type; 235. { 236. register struct mkroom *sroom; 237. 238. if (type == BADFOODSHOP) { 239. if ((sroom = pick_room(TRUE)) != 0) { 240. sroom->rtype = type; 241. fill_zoo(sroom); 242. } 243. } 244. else if ((sroom = pick_room(FALSE)) != 0) { 245. sroom->rtype = type; 246. fill_zoo(sroom); 247. } 248. } 249. 250. void 251. fill_zoo(sroom) 252. struct mkroom *sroom; 253. { 254. struct monst *mon; 255. register int sx,sy,i; 256. int sh, tx, ty, goldlim, type = sroom->rtype; 257. int rmno = (sroom - rooms) + ROOMOFFSET; 258. coord mm; 259. 260. #ifdef GCC_WARN 261. tx = ty = goldlim = 0; 262. #endif 263. 264. sh = sroom->fdoor; 265. switch(type) { 266. case COURT: 267. case GIANTCOURT: 268. if(level.flags.is_maze_lev) { 269. for(tx = sroom->lx; tx <= sroom->hx; tx++) 270. for(ty = sroom->ly; ty <= sroom->hy; ty++) 271. if(IS_THRONE(levl[tx][ty].typ)) 272. goto throne_placed; 273. } 274. 275. i = 100; 276. do { /* don't place throne on top of stairs */ 277. (void) somexy(sroom, &mm); 278. tx = mm.x; ty = mm.y; 279. } while (occupied((xchar)tx, (xchar)ty) && --i > 0); 280. throne_placed: 281. /* TODO: try to ensure the enthroned monster is an M2_PRINCE */ 282. break; 283. case BEEHIVE: 284. case MIGOHIVE: 285. tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2; 286. ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2; 287. if(sroom->irregular) { 288. /* center might not be valid, so put queen elsewhere */ 289. if ((int) levl[tx][ty].roomno != rmno || 290. levl[tx][ty].edge) { 291. (void) somexy(sroom, &mm); 292. tx = mm.x; ty = mm.y; 293. } 294. } 295. break; 296. case ZOO: 297. case LEPREHALL: 298. goldlim = 500 * level_difficulty(); 299. break; 300. case DRAGONLAIR: 301. goldlim = 1500 * level_difficulty(); 302. break; 303. } 304. for(sx = sroom->lx; sx <= sroom->hx; sx++) 305. for(sy = sroom->ly; sy <= sroom->hy; sy++) { 306. if(sroom->irregular) { 307. if ((int) levl[sx][sy].roomno != rmno || 308. levl[sx][sy].edge || 309. (sroom->doorct && 310. distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1)) 311. continue; 312. } else if(!SPACE_POS(levl[sx][sy].typ) || 313. (sroom->doorct && 314. ((sx == sroom->lx && doors[sh].x == sx-1) || 315. (sx == sroom->hx && doors[sh].x == sx+1) || 316. (sy == sroom->ly && doors[sh].y == sy-1) || 317. (sy == sroom->hy && doors[sh].y == sy+1)))) 318. continue; 319. /* don't place monster on explicitly placed throne */ 320. if(type == COURT && IS_THRONE(levl[sx][sy].typ)) 321. continue; 322. mon = makemon( 323. (type == COURT) ? courtmon() : 324. (type == BARRACKS) ? squadmon() : 325. (type == MORGUE) ? morguemon() : 326. (type == FUNGUSFARM) ? fungus() : 327. (type == BEEHIVE) ? 328. (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 329. &mons[PM_KILLER_BEE]) : 330. (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] : 331. (type == COCKNEST) ? 332. (rn2(4) ? &mons[PM_COCKATRICE] : 333. &mons[PM_CHICKATRICE]) : 334. (type == ANTHOLE) ? antholemon() : 335. (type == DRAGONLAIR) ? mkclass(S_DRAGON,0) : 336. (type == LEMUREPIT)? 337. (!rn2(10)? &mons[PM_HORNED_DEVIL] : 338. &mons[PM_LEMURE]) : 339. (type == MIGOHIVE)? 340. (sx == tx && sy == ty? &mons[PM_MIGO_QUEEN] : 341. (rn2(2)? &mons[PM_MIGO_DRONE] : &mons[PM_MIGO_WARRIOR])) : 342. (type == BADFOODSHOP) ? mkclass(S_BAD_FOOD,0) : 343. (type == REALZOO) ? realzoomon() : 344. (type == GIANTCOURT) ? mkclass(S_GIANT,0) : 345. (struct permonst *) 0, 346. sx, sy, NO_MM_FLAGS); 347. 348. if(mon) { 349. mon->msleeping = 1; 350. if (type==COURT && mon->mpeaceful) { 351. mon->mpeaceful = 0; 352. set_malign(mon); 353. } 354. } 355. switch(type) { 356. case ZOO: 357. case DRAGONLAIR: 358. case LEPREHALL: 359. if(sroom->doorct) 360. { 361. int distval = dist2(sx,sy,doors[sh].x,doors[sh].y); 362. i = sq(distval); 363. } 364. else 365. i = goldlim; 366. if(i >= goldlim) i = 5*level_difficulty(); 367. goldlim -= i; 368. (void) mkgold((long) rn1(i, 10), sx, sy); 369. break; 370. case MORGUE: 371. if(!rn2(5)) 372. (void) mk_tt_object(CORPSE, sx, sy); 373. if(!rn2(10)) /* lots of treasure buried with dead */ 374. (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, 375. sx, sy, TRUE, FALSE); 376. if (!rn2(5)) 377. make_grave(sx, sy, (char *)0); 378. break; 379. case BEEHIVE: 380. if(!rn2(3)) 381. (void) mksobj_at(LUMP_OF_ROYAL_JELLY, 382. sx, sy, TRUE, FALSE); 383. break; 384. case FUNGUSFARM: 385. if (!rn2(3)) 386. (void) mksobj_at(SLIME_MOLD, sx, sy, TRUE, FALSE); 387. break; 388. case MIGOHIVE: 389. switch (rn2(10)) { 390. case 9: 391. mksobj_at(DIAMOND, sx, sy, TRUE, FALSE); 392. break; 393. case 8: 394. mksobj_at(RUBY, sx, sy, TRUE, FALSE); 395. break; 396. case 7: 397. case 6: 398. mksobj_at(AGATE, sx, sy, TRUE, FALSE); 399. break; 400. case 5: 401. case 4: 402. mksobj_at(FLUORITE, sx, sy, TRUE, FALSE); 403. break; 404. default: 405. break; 406. } 407. break; 408. case BARRACKS: 409. if(!rn2(20)) /* the payroll and some loot */ 410. (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, 411. sx, sy, TRUE, FALSE); 412. if (!rn2(5)) 413. make_grave(sx, sy, (char *)0); 414. break; 415. case COCKNEST: 416. if(!rn2(3)) { 417. struct obj *sobj = mk_tt_object(STATUE, sx, sy); 418. 419. if (sobj) { 420. for (i = rn2(5); i; i--) 421. (void) add_to_container(sobj, 422. mkobj(RANDOM_CLASS, FALSE)); 423. sobj->owt = weight(sobj); 424. } 425. } 426. break; 427. case ANTHOLE: 428. if(!rn2(3)) 429. (void) mkobj_at(FOOD_CLASS, sx, sy, FALSE); 430. break; 431. } 432. } 433. switch (type) { 434. case COURT: 435. case GIANTCOURT: 436. { 437. struct obj *chest; 438. levl[tx][ty].typ = THRONE; 439. (void) somexy(sroom, &mm); 440. (void) mkgold((long) rn1(50 * level_difficulty(),10), mm.x, mm.y); 441. /* the royal coffers */ 442. chest = mksobj_at(CHEST, mm.x, mm.y, TRUE, FALSE); 443. chest->spe = 2; /* so it can be found later */ 444. level.flags.has_court = 1; 445. break; 446. } 447. case BARRACKS: 448. level.flags.has_barracks = 1; 449. break; 450. case REALZOO: 451. case ZOO: 452. level.flags.has_zoo = 1; 453. break; 454. case MORGUE: 455. level.flags.has_morgue = 1; 456. break; 457. case SWAMP: 458. level.flags.has_swamp = 1; 459. break; 460. case BEEHIVE: 461. level.flags.has_beehive = 1; 462. break; 463. case LEMUREPIT: 464. level.flags.has_lemurepit = 1; 465. break; 466. case MIGOHIVE: 467. level.flags.has_migohive = 1; 468. break; 469. case FUNGUSFARM: 470. level.flags.has_fungusfarm = 1; 471. break; 472. } 473. } 474. 475. /* make a swarm of undead around mm */ 476. void 477. mkundead(mm, revive_corpses, mm_flags) 478. coord *mm; 479. boolean revive_corpses; 480. int mm_flags; 481. { 482. int cnt = (level_difficulty() + 1)/10 + rnd(5); 483. struct permonst *mdat; 484. struct obj *otmp; 485. coord cc; 486. 487. while (cnt--) { 488. mdat = morguemon(); 489. if (enexto(&cc, mm->x, mm->y, mdat) && 490. (!revive_corpses || 491. !(otmp = sobj_at(CORPSE, cc.x, cc.y)) || 492. !revive(otmp))) 493. (void) makemon(mdat, cc.x, cc.y, mm_flags); 494. } 495. level.flags.graveyard = TRUE; /* reduced chance for undead corpse */ 496. } 497. 498. STATIC_OVL struct permonst * 499. morguemon() 500. { 501. register int i = rn2(100), hd = rn2(level_difficulty()); 502. 503. if(hd > 10 && i < 10) 504. return((Inhell || In_endgame(&u.uz)) ? mkclass(S_DEMON,0) : 505. &mons[ndemon(A_NONE)]); 506. if(hd > 8 && i > 85) 507. return(mkclass(S_VAMPIRE,0)); 508. 509. return((i < 20) ? &mons[PM_GHOST] 510. : (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE,0)); 511. } 512. 513. struct permonst * 514. antholemon() 515. { 516. int mtyp; 517. 518. /* Same monsters within a level, different ones between levels */ 519. switch ((level_difficulty() + ((long)u.ubirthday)) % 4) { 520. default: mtyp = PM_GIANT_ANT; break; 521. case 0: mtyp = PM_SOLDIER_ANT; break; 522. case 1: mtyp = PM_FIRE_ANT; break; 523. case 2: mtyp = PM_SNOW_ANT; break; 524. } 525. return ((mvitals[mtyp].mvflags & G_GONE) ? 526. (struct permonst *)0 : &mons[mtyp]); 527. } 528. 529. 530. STATIC_OVL struct permonst * 531. fungus() 532. { 533. register int i, hd = level_difficulty(), mtyp = 0; 534. 535. i = rn2(hd > 20 ? 17 : hd > 12 ? 14 : 12); 536. 537. switch (i) { 538. case 0: 539. case 1: mtyp = PM_LICHEN; break; 540. case 2: mtyp = PM_BROWN_MOLD; break; 541. case 3: mtyp = PM_YELLOW_MOLD; break; 542. case 4: mtyp = PM_GREEN_MOLD; break; 543. case 5: mtyp = PM_RED_MOLD; break; 544. case 6: mtyp = PM_SHRIEKER; break; 545. case 7: mtyp = PM_VIOLET_FUNGUS; break; 546. case 8: mtyp = PM_BLUE_JELLY; break; 547. case 9: mtyp = PM_DISGUSTING_MOLD; break; 548. case 10: mtyp = PM_BLACK_MOLD; break; 549. case 11: mtyp = PM_GRAY_OOZE; break; 550. /* Following only after level 12... */ 551. case 12: mtyp = PM_SPOTTED_JELLY; break; 552. case 13: mtyp = PM_BROWN_PUDDING; break; 553. /* Following only after level 20... */ 554. case 14: mtyp = PM_GREEN_SLIME; break; 555. case 15: mtyp = PM_BLACK_PUDDING; break; 556. case 16: mtyp = PM_OCHRE_JELLY; break; 557. } 558. 559. return ((mvitals[mtyp].mvflags & G_GONE) ? 560. (struct permonst *)0 : &mons[mtyp]); 561. } 562. 563. STATIC_OVL void 564. mkswamp() /* Michiel Huisjes & Fred de Wilde */ 565. { 566. register struct mkroom *sroom; 567. register int sx,sy,i,eelct = 0; 568. 569. for(i=0; i<5; i++) { /* turn up to 5 rooms swampy */ 570. sroom = &rooms[rn2(nroom)]; 571. if(sroom->hx < 0 || sroom->rtype != OROOM || 572. has_upstairs(sroom) || has_dnstairs(sroom)) 573. continue; 574. 575. /* satisfied; make a swamp */ 576. sroom->rtype = SWAMP; 577. for(sx = sroom->lx; sx <= sroom->hx; sx++) 578. for(sy = sroom->ly; sy <= sroom->hy; sy++) 579. if(!OBJ_AT(sx, sy) && 580. !MON_AT(sx, sy) && !t_at(sx,sy) && !nexttodoor(sx,sy)) { 581. if((sx+sy)%2) { 582. levl[sx][sy].typ = POOL; 583. if(!eelct || !rn2(4)) { 584. /* mkclass() won't do, as we might get kraken */ 585. (void) makemon(rn2(5) ? &mons[PM_GIANT_EEL] 586. : rn2(2) ? &mons[PM_PIRANHA] 587. : &mons[PM_ELECTRIC_EEL], 588. sx, sy, NO_MM_FLAGS); 589. eelct++; 590. } 591. } else 592. if(!rn2(4)) /* swamps tend to be moldy */ 593. (void) makemon(mkclass(S_FUNGUS,0), 594. sx, sy, NO_MM_FLAGS); 595. } 596. level.flags.has_swamp = 1; 597. } 598. } 599. 600. STATIC_OVL coord * 601. shrine_pos(roomno) 602. int roomno; 603. { 604. static coord buf; 605. struct mkroom *troom = &rooms[roomno - ROOMOFFSET]; 606. 607. buf.x = troom->lx + ((troom->hx - troom->lx) / 2); 608. buf.y = troom->ly + ((troom->hy - troom->ly) / 2); 609. return(&buf); 610. } 611. 612. STATIC_OVL void 613. mktemple() 614. { 615. register struct mkroom *sroom; 616. coord *shrine_spot; 617. register struct rm *lev; 618. 619. if(!(sroom = pick_room(TRUE))) return; 620. 621. /* set up Priest and shrine */ 622. sroom->rtype = TEMPLE; 623. /* 624. * In temples, shrines are blessed altars 625. * located in the center of the room 626. */ 627. shrine_spot = shrine_pos((sroom - rooms) + ROOMOFFSET); 628. lev = &levl[shrine_spot->x][shrine_spot->y]; 629. lev->typ = ALTAR; 630. lev->altarmask = induced_align(80); 631. priestini(&u.uz, sroom, shrine_spot->x, shrine_spot->y, FALSE); 632. lev->altarmask |= AM_SHRINE; 633. level.flags.has_temple = 1; 634. } 635. 636. boolean 637. nexttodoor(sx,sy) 638. register int sx, sy; 639. { 640. register int dx, dy; 641. register struct rm *lev; 642. for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) { 643. if(!isok(sx+dx, sy+dy)) continue; 644. if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) || 645. lev->typ == SDOOR) 646. return(TRUE); 647. } 648. return(FALSE); 649. } 650. 651. boolean 652. has_dnstairs(sroom) 653. register struct mkroom *sroom; 654. { 655. if (sroom == dnstairs_room) 656. return TRUE; 657. if (sstairs.sx && !sstairs.up) 658. return((boolean)(sroom == sstairs_room)); 659. return FALSE; 660. } 661. 662. boolean 663. has_upstairs(sroom) 664. register struct mkroom *sroom; 665. { 666. if (sroom == upstairs_room) 667. return TRUE; 668. if (sstairs.sx && sstairs.up) 669. return((boolean)(sroom == sstairs_room)); 670. return FALSE; 671. } 672. 673. #endif /* OVLB */ 674. #ifdef OVL0 675. 676. int 677. somex(croom) 678. register struct mkroom *croom; 679. { 680. return rn2(croom->hx-croom->lx+1) + croom->lx; 681. } 682. 683. int 684. somey(croom) 685. register struct mkroom *croom; 686. { 687. return rn2(croom->hy-croom->ly+1) + croom->ly; 688. } 689. 690. boolean 691. inside_room(croom, x, y) 692. struct mkroom *croom; 693. xchar x, y; 694. { 695. return((boolean)(x >= croom->lx-1 && x <= croom->hx+1 && 696. y >= croom->ly-1 && y <= croom->hy+1)); 697. } 698. 699. boolean 700. somexy(croom, c) 701. struct mkroom *croom; 702. coord *c; 703. { 704. int try_cnt = 0; 705. int i; 706. 707. if (croom->irregular) { 708. i = (croom - rooms) + ROOMOFFSET; 709. 710. while(try_cnt++ < 100) { 711. c->x = somex(croom); 712. c->y = somey(croom); 713. if (!levl[c->x][c->y].edge && 714. (int) levl[c->x][c->y].roomno == i) 715. return TRUE; 716. } 717. /* try harder; exhaustively search until one is found */ 718. for(c->x = croom->lx; c->x <= croom->hx; c->x++) 719. for(c->y = croom->ly; c->y <= croom->hy; c->y++) 720. if (!levl[c->x][c->y].edge && 721. (int) levl[c->x][c->y].roomno == i) 722. return TRUE; 723. return FALSE; 724. } 725. 726. if (!croom->nsubrooms) { 727. c->x = somex(croom); 728. c->y = somey(croom); 729. return TRUE; 730. } 731. 732. /* Check that coords doesn't fall into a subroom or into a wall */ 733. 734. while(try_cnt++ < 100) { 735. c->x = somex(croom); 736. c->y = somey(croom); 737. if (IS_WALL(levl[c->x][c->y].typ)) 738. continue; 739. for(i=0 ; i<croom->nsubrooms;i++) 740. if(inside_room(croom->sbrooms[i], c->x, c->y)) 741. goto you_lose; 742. break; 743. you_lose: ; 744. } 745. if (try_cnt >= 100) 746. return FALSE; 747. return TRUE; 748. } 749. 750. /* 751. * Search for a special room given its type (zoo, court, etc...) 752. * Special values : 753. * - ANY_SHOP 754. * - ANY_TYPE 755. */ 756. 757. struct mkroom * 758. search_special(type) 759. schar type; 760. { 761. register struct mkroom *croom; 762. 763. for(croom = &rooms[0]; croom->hx >= 0; croom++) 764. if((type == ANY_TYPE && croom->rtype != OROOM) || 765. (type == ANY_SHOP && croom->rtype >= SHOPBASE) || 766. croom->rtype == type) 767. return croom; 768. for(croom = &subrooms[0]; croom->hx >= 0; croom++) 769. if((type == ANY_TYPE && croom->rtype != OROOM) || 770. (type == ANY_SHOP && croom->rtype >= SHOPBASE) || 771. croom->rtype == type) 772. return croom; 773. return (struct mkroom *) 0; 774. } 775. 776. #endif /* OVL0 */ 777. #ifdef OVLB 778. 779. struct permonst * 780. courtmon() 781. { 782. int i = rn2(60) + rn2(3*level_difficulty()); 783. if (i > 200) return(mkclass(S_DRAGON,0)); 784. else if (i > 130) return(mkclass(S_GIANT,0)); 785. else if (i > 85) return(mkclass(S_TROLL,0)); 786. else if (i > 75) return(mkclass(S_CENTAUR,0)); 787. else if (i > 60) return(mkclass(S_ORC,0)); 788. else if (i > 45) return(&mons[PM_BUGBEAR]); 789. else if (i > 30) return(&mons[PM_HOBGOBLIN]); 790. else if (i > 15) return(mkclass(S_GNOME,0)); 791. else return(mkclass(S_KOBOLD,0)); 792. } 793. 794. struct permonst * 795. realzoomon() 796. { 797. int i = rn2(60) + rn2(3*level_difficulty()); 798. if (i > 175) return(&mons[PM_JUMBO_THE_ELEPHANT]); 799. else if (i > 115) return(&mons[PM_MASTODON]); 800. else if (i > 85) return(&mons[PM_PYTHON]); 801. else if (i > 70) return(&mons[PM_MUMAK]); 802. else if (i > 55) return(&mons[PM_TIGER]); 803. else if (i > 45) return(&mons[PM_PANTHER]); 804. else if (i > 25) return(&mons[PM_JAGUAR]); 805. else if (i > 15) return(&mons[PM_APE]); 806. else return(&mons[PM_MONKEY]); 807. } 808. 809. #define NSTYPES (PM_CAPTAIN - PM_SOLDIER + 1) 810. 811. static struct { 812. unsigned pm; 813. unsigned prob; 814. } squadprob[NSTYPES] = { 815. {PM_SOLDIER, 80}, {PM_SERGEANT, 15}, {PM_LIEUTENANT, 4}, {PM_CAPTAIN, 1} 816. }; 817. 818. STATIC_OVL struct permonst * 819. squadmon() /* return soldier types. */ 820. { 821. int sel_prob, i, cpro, mndx; 822. 823. sel_prob = rnd(80+level_difficulty()); 824. 825. cpro = 0; 826. for (i = 0; i < NSTYPES; i++) { 827. cpro += squadprob[i].prob; 828. if (cpro > sel_prob) { 829. mndx = squadprob[i].pm; 830. goto gotone; 831. } 832. } 833. mndx = squadprob[rn2(NSTYPES)].pm; 834. gotone: 835. if (!(mvitals[mndx].mvflags & G_GONE)) return(&mons[mndx]); 836. else return((struct permonst *) 0); 837. } 838. 839. /* 840. * save_room : A recursive function that saves a room and its subrooms 841. * (if any). 842. */ 843. 844. STATIC_OVL void 845. save_room(fd, r) 846. int fd; 847. struct mkroom *r; 848. { 849. short i; 850. /* 851. * Well, I really should write only useful information instead 852. * of writing the whole structure. That is I should not write 853. * the subrooms pointers, but who cares ? 854. */ 855. bwrite(fd, (genericptr_t) r, sizeof(struct mkroom)); 856. for(i=0; i<r->nsubrooms; i++) 857. save_room(fd, r->sbrooms[i]); 858. } 859. 860. /* 861. * save_rooms : Save all the rooms on disk! 862. */ 863. 864. void 865. save_rooms(fd) 866. int fd; 867. { 868. short i; 869. 870. /* First, write the number of rooms */ 871. bwrite(fd, (genericptr_t) &nroom, sizeof(nroom)); 872. for(i=0; i<nroom; i++) 873. save_room(fd, &rooms[i]); 874. } 875. 876. STATIC_OVL void 877. rest_room(fd, r) 878. int fd; 879. struct mkroom *r; 880. { 881. short i; 882. 883. mread(fd, (genericptr_t) r, sizeof(struct mkroom)); 884. for(i=0; i<r->nsubrooms; i++) { 885. r->sbrooms[i] = &subrooms[nsubroom]; 886. rest_room(fd, &subrooms[nsubroom]); 887. subrooms[nsubroom++].resident = (struct monst *)0; 888. } 889. } 890. 891. /* 892. * rest_rooms : That's for restoring rooms. Read the rooms structure from 893. * the disk. 894. */ 895. 896. void 897. rest_rooms(fd) 898. int fd; 899. { 900. short i; 901. 902. mread(fd, (genericptr_t) &nroom, sizeof(nroom)); 903. nsubroom = 0; 904. for(i = 0; i<nroom; i++) { 905. rest_room(fd, &rooms[i]); 906. rooms[i].resident = (struct monst *)0; 907. } 908. rooms[nroom].hx = -1; /* restore ending flags */ 909. subrooms[nsubroom].hx = -1; 910. } 911. #endif /* OVLB */ 912. 913. /*mkroom.c*/