Source:NetHack 3.4.0/mkroom.c

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