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