Source:Mkroom.c

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. 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(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.   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 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.    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.   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.   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.   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.   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.   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.   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.   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.   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.   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.   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.   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.   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.  559.  int 560. somex(croom) 561. register struct mkroom *croom; 562. {  563.  	return rn2(croom->hx-croom->lx+1) + croom->lx; 564. }  565.   566.  int 567. somey(croom) 568. register struct mkroom *croom; 569. {  570.  	return rn2(croom->hy-croom->ly+1) + croom->ly; 571. }  572.   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.   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 ; insubrooms;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.   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.  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.   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.   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; insubrooms; i++) 725. 	    save_room(fd, r->sbrooms[i]); 726. }  727.   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; insubrooms; i++) { 753. 		r->sbrooms[i] = &subrooms[nsubroom]; 754. 		rest_room(fd, &subrooms[nsubroom]); 755. 		subrooms[nsubroom++].resident = (struct monst *)0; 756. 	}  757.  }  758.   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*/