Source:NetHack 3.2.0/mkroom.c

Below is the full text to mkroom.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/mkroom.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

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