abstract
| - 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 [[SLASH'EM 0.0.7E7F2/mkroom.c#line123]], for example. The latest source code for vanilla NetHack is at Source code. 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 ; insubrooms;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; insubrooms; 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 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; insubrooms; 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 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*/
|