Source:NetHack 3.1.0/mkroom.c

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