Source:NetHack 3.3.0/mkroom.c

Below is the full text to mkroom.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.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.3	97/05/25	*/ 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 = 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); 329. 			if (!rn2(5) && levl[sx][sy].typ == ROOM) 330. 			    levl[sx][sy].typ = GRAVE; 331. 			break; 332. 		    case BEEHIVE: 333. 			if(!rn2(3)) 334. 			    (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy, TRUE); 335. 			break; 336. 		    case BARRACKS: 337. 			if(!rn2(20))	/* the payroll and some loot */ 338. 			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,  339.  					     sx, sy, TRUE); 340. 			break; 341. 		    case COCKNEST: 342. 			if(!rn2(3)) { 343. 			    struct obj *sobj = mk_tt_object(STATUE, sx, sy); 344.  345.  			    if (sobj) 346. 			    	for (i = rn2(5); i; i--) 347. 			    	    add_to_container(sobj, mkobj(RANDOM_CLASS, FALSE)); 348. 			}  349.  			break; 350. 		    case ANTHOLE: 351. 			if(!rn2(3)) 352. 			    (void) mkobj_at(FOOD_CLASS, sx, sy, TRUE); 353. 			break; 354. 		}  355.  	    }  356.  	switch (type) { 357. 	      case COURT: 358. 		{  359.  		  struct obj *chest; 360. 		  levl[tx][ty].typ = THRONE; 361. 		  (void) somexy(sroom, &mm); 362. 		  (void) mkgold((long) rn1(50 * level_difficulty,10), mm.x, mm.y); 363. 		  chest = mksobj_at(CHEST, mm.x, mm.y, TRUE); /* the royal coffers */ 364. 		  chest->spe = 2; /* so it can be found later */ 365. 		  level.flags.has_court = 1; 366. 		  break; 367. 		}  368.  	      case BARRACKS: 369. 		  level.flags.has_barracks = 1; 370. 		  break; 371. 	      case ZOO: 372. 		  level.flags.has_zoo = 1; 373. 		  break; 374. 	      case MORGUE: 375. 		  level.flags.has_morgue = 1; 376. 		  break; 377. 	      case SWAMP: 378. 		  level.flags.has_swamp = 1; 379. 		  break; 380. 	      case BEEHIVE: 381. 		  level.flags.has_beehive = 1; 382. 		  break; 383. 	}  384.  }  385.   386.  /* make a swarm of undead around mm */ 387. void 388. mkundead(mm, revive_corpses, mm_flags) 389. coord *mm; 390. boolean revive_corpses; 391. int mm_flags; 392. {  393.  	int cnt = (level_difficulty + 1)/10 + rnd(5); 394. 	struct permonst *mdat; 395. 	struct obj *otmp; 396. 	coord cc; 397.  398.  	while (cnt--) { 399. 	    mdat = morguemon; 400. 	    if (enexto(&cc, mm->x, mm->y, mdat) &&  401.  		    (!revive_corpses || 402. 		     !(otmp = sobj_at(CORPSE, cc.x, cc.y)) || 403. 		     !revive(otmp))) 404. 		(void) makemon(mdat, cc.x, cc.y, mm_flags); 405. 	}  406.  	level.flags.graveyard = TRUE;	/* reduced chance for undead corpse */ 407. }  408.   409.  STATIC_OVL struct permonst * 410. morguemon 411. {  412.  	register int i = rn2(100), hd = rn2(level_difficulty); 413.  414.  	if(hd > 10 && i < 10) 415. 		return((Inhell || In_endgame(&u.uz)) ? mkclass(S_DEMON,0) :  416.  						       &mons[ndemon(A_NONE)]); 417. 	if(hd > 8 && i > 85) 418. 		return(mkclass(S_VAMPIRE,0)); 419.  420.  	return((i < 20) ? &mons[PM_GHOST]  421.  			: (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE,0)); 422. }  423.   424.  STATIC_OVL struct permonst * 425. antholemon 426. {  427.  	int mtyp; 428.  429.  	/* Same monsters within a level, different ones between levels */ 430. 	switch ((level_difficulty + ((long)u.ubirthday)) % 3) { 431. 	default:	mtyp = PM_GIANT_ANT; break; 432. 	case 0:		mtyp = PM_SOLDIER_ANT; break; 433. 	case 1:		mtyp = PM_FIRE_ANT; break; 434. 	}  435.  	return ((mvitals[mtyp].mvflags & G_GONE) ?  436.  			(struct permonst *)0 : &mons[mtyp]); 437. }  438.   439.  STATIC_OVL void 440. mkswamp	/* Michiel Huisjes & Fred de Wilde */ 441. {  442.  	register struct mkroom *sroom; 443. 	register int sx,sy,i,eelct = 0; 444.  445.  	for(i=0; i<5; i++) {		/* turn up to 5 rooms swampy */ 446. 		sroom = &rooms[rn2(nroom)]; 447. 		if(sroom->hx < 0 || sroom->rtype != OROOM ||  448.  		   has_upstairs(sroom) || has_dnstairs(sroom)) 449. 			continue; 450.  451.  		/* satisfied; make a swamp */ 452. 		sroom->rtype = SWAMP; 453. 		for(sx = sroom->lx; sx <= sroom->hx; sx++) 454. 		for(sy = sroom->ly; sy <= sroom->hy; sy++) 455. 		if(!OBJ_AT(sx, sy) &&  456.  		   !MON_AT(sx, sy) && !t_at(sx,sy) && !nexttodoor(sx,sy)) { 457. 		    if((sx+sy)%2) { 458. 			levl[sx][sy].typ = POOL; 459. 			if(!eelct || !rn2(4)) { 460. 			    /* mkclass won't do, as we might get kraken */ 461. 			    (void) makemon(rn2(5) ? &mons[PM_GIANT_EEL]  462.  						  : &mons[PM_ELECTRIC_EEL],  463.  						sx, sy, NO_MM_FLAGS); 464. 			    eelct++; 465. 			}  466.  		    } else 467. 			if(!rn2(4))	/* swamps tend to be moldy */ 468. 			    (void) makemon(mkclass(S_FUNGUS,0),  469.  						sx, sy, NO_MM_FLAGS); 470. 		}  471.  		level.flags.has_swamp = 1; 472. 	}  473.  }  474.   475.  STATIC_OVL coord * 476. shrine_pos(roomno) 477. int roomno; 478. {  479.  	static coord buf; 480. 	struct mkroom *troom = &rooms[roomno - ROOMOFFSET]; 481.  482.  	buf.x = troom->lx + ((troom->hx - troom->lx) / 2); 483. 	buf.y = troom->ly + ((troom->hy - troom->ly) / 2); 484. 	return(&buf); 485. }  486.   487.  STATIC_OVL void 488. mktemple 489. {  490.  	register struct mkroom *sroom; 491. 	coord *shrine_spot; 492. 	register struct rm *lev; 493.  494.  	if(!(sroom = pick_room(TRUE))) return; 495.  496.  	/* set up Priest and shrine */ 497. 	sroom->rtype = TEMPLE; 498. 	/*  499.  	 * In temples, shrines are blessed altars 500. 	 * located in the center of the room 501. 	 */  502.  	shrine_spot = shrine_pos((sroom - rooms) + ROOMOFFSET); 503. 	lev = &levl[shrine_spot->x][shrine_spot->y]; 504. 	lev->typ = ALTAR; 505. 	lev->altarmask = induced_align(80); 506. 	priestini(&u.uz, sroom, shrine_spot->x, shrine_spot->y, FALSE); 507. 	lev->altarmask |= AM_SHRINE; 508. 	level.flags.has_temple = 1; 509. }  510.   511.  boolean 512. nexttodoor(sx,sy) 513. register int sx, sy; 514. {  515.  	register int dx, dy; 516. 	register struct rm *lev; 517. 	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) { 518. 		if(!isok(sx+dx, sy+dy)) continue; 519. 		if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||  520.  		    lev->typ == SDOOR) 521. 			return(TRUE); 522. 	}  523.  	return(FALSE); 524. }  525.   526.  boolean 527. has_dnstairs(sroom) 528. register struct mkroom *sroom; 529. {  530.  	if (sroom == dnstairs_room) 531. 		return TRUE; 532. 	if (sstairs.sx && !sstairs.up) 533. 		return((boolean)(sroom == sstairs_room)); 534. 	return FALSE; 535. }  536.   537.  boolean 538. has_upstairs(sroom) 539. register struct mkroom *sroom; 540. {  541.  	if (sroom == upstairs_room) 542. 		return TRUE; 543. 	if (sstairs.sx && sstairs.up) 544. 		return((boolean)(sroom == sstairs_room)); 545. 	return FALSE; 546. }  547.   548.  #endif /* OVLB */ 549. #ifdef OVL0 550.  551.  int 552. somex(croom) 553. register struct mkroom *croom; 554. {  555.  	return rn2(croom->hx-croom->lx+1) + croom->lx; 556. }  557.   558.  int 559. somey(croom) 560. register struct mkroom *croom; 561. {  562.  	return rn2(croom->hy-croom->ly+1) + croom->ly; 563. }  564.   565.  boolean 566. inside_room(croom, x, y)  567. struct mkroom *croom; 568. xchar x, y;  569. { 570.  	return((boolean)(x >= croom->lx-1 && x <= croom->hx+1 && 571. 		y >= croom->ly-1 && y <= croom->hy+1)); 572. }  573.   574.  boolean 575. somexy(croom, c)  576. struct mkroom *croom; 577. coord *c; 578. {  579.  	int try_cnt = 0; 580. 	int i;  581. 582. 	if (croom->irregular) { 583. 	    i = (croom - rooms) + ROOMOFFSET; 584.  585.  	    while(try_cnt++ < 100) { 586. 		c->x = somex(croom); 587. 		c->y = somey(croom); 588. 		if (!levl[c->x][c->y].edge &&  589.  			(int) levl[c->x][c->y].roomno == i)  590. return TRUE; 591. 	    }  592.  	    /* try harder; exhaustively search until one is found */ 593. 	    for(c->x = croom->lx; c->x <= croom->hx; c->x++) 594. 		for(c->y = croom->ly; c->y <= croom->hy; c->y++) 595. 		    if (!levl[c->x][c->y].edge &&  596.  			    (int) levl[c->x][c->y].roomno == i)  597. return TRUE; 598. 	    return FALSE; 599. 	}  600.   601.  	if (!croom->nsubrooms) { 602. 		c->x = somex(croom); 603. 		c->y = somey(croom); 604. 		return TRUE; 605. 	}  606.   607.  	/* Check that coords doesn't fall into a subroom or into a wall */ 608.  609.  	while(try_cnt++ < 100) { 610. 		c->x = somex(croom); 611. 		c->y = somey(croom); 612. 		if (IS_WALL(levl[c->x][c->y].typ)) 613. 		    continue; 614. 		for(i=0 ; insubrooms;i++) 615. 		    if(inside_room(croom->sbrooms[i], c->x, c->y)) 616. 			goto you_lose; 617. 		break; 618. you_lose:	; 619. 	}  620.  	if (try_cnt >= 100) 621. 	    return FALSE; 622. 	return TRUE; 623. }  624.   625.  /*  626.   * Search for a special room given its type (zoo, court, etc...) 627.  *	Special values : 628.  *		- ANY_SHOP 629.  *		- ANY_TYPE 630.  */  631.   632.  struct mkroom * 633. search_special(type) 634. schar type; 635. {  636.  	register struct mkroom *croom; 637.  638.  	for(croom = &rooms[0]; croom->hx >= 0; croom++) 639. 	    if((type == ANY_TYPE && croom->rtype != OROOM) ||  640.  	       (type == ANY_SHOP && croom->rtype >= SHOPBASE) ||  641.  	       croom->rtype == type) 642. 		return croom; 643. 	for(croom = &subrooms[0]; croom->hx >= 0; croom++) 644. 	    if((type == ANY_TYPE && croom->rtype != OROOM) ||  645.  	       (type == ANY_SHOP && croom->rtype >= SHOPBASE) ||  646.  	       croom->rtype == type) 647. 		return croom; 648. 	return (struct mkroom *) 0; 649. }  650.   651.  #endif /* OVL0 */ 652. #ifdef OVLB 653.  654.  struct permonst * 655. courtmon 656. {  657.  	int     i = rn2(60) + rn2(3*level_difficulty); 658. 	if (i > 100)		return(mkclass(S_DRAGON,0)); 659. 	else if (i > 95)	return(mkclass(S_GIANT,0)); 660. 	else if (i > 85)	return(mkclass(S_TROLL,0)); 661. 	else if (i > 75)	return(mkclass(S_CENTAUR,0)); 662. 	else if (i > 60)	return(mkclass(S_ORC,0)); 663. 	else if (i > 45)	return(&mons[PM_BUGBEAR]); 664. 	else if (i > 30)	return(&mons[PM_HOBGOBLIN]); 665. 	else if (i > 15)	return(mkclass(S_GNOME,0)); 666. 	else			return(mkclass(S_KOBOLD,0)); 667. }  668.   669.  #define NSTYPES (PM_CAPTAIN - PM_SOLDIER + 1) 670.  671.  static struct { 672.     unsigned	pm; 673.     unsigned	prob; 674. } squadprob[NSTYPES] = { 675.     {PM_SOLDIER, 80}, {PM_SERGEANT, 15}, {PM_LIEUTENANT, 4}, {PM_CAPTAIN, 1} 676. };  677.   678.  STATIC_OVL struct permonst * 679. squadmon		/* return soldier types. */ 680.  {  681.  	int sel_prob, i, cpro, mndx; 682.  683.  	sel_prob = rnd(80+level_difficulty); 684.  685.  	cpro = 0; 686. 	for (i = 0; i < NSTYPES; i++) { 687. 	    cpro += squadprob[i].prob; 688. 	    if (cpro > sel_prob) { 689. 		mndx = squadprob[i].pm; 690. 		goto gotone; 691. 	    }  692.  	}  693.  	mndx = squadprob[rn2(NSTYPES)].pm; 694. gotone: 695. 	if (!(mvitals[mndx].mvflags & G_GONE)) return(&mons[mndx]); 696. 	else			    return((struct permonst *) 0); 697. }  698.   699.  /*  700.   * save_room : A recursive function that saves a room and its subrooms 701.  * (if any). 702.  */  703.   704.  STATIC_OVL void 705. save_room(fd, r)  706. int	fd; 707. struct mkroom *r; 708. {  709.  	short i;  710. /* 711.  	 * Well, I really should write only useful information instead 712. 	 * of writing the whole structure. That is I should not write 713. 	 * the subrooms pointers, but who cares ? 714. 	 */  715.  	bwrite(fd, (genericptr_t) r, sizeof(struct mkroom)); 716. 	for(i=0; insubrooms; i++) 717. 	    save_room(fd, r->sbrooms[i]); 718. }  719.   720.  /*  721.   * save_rooms : Save all the rooms on disk! 722.  */  723.   724.  void 725. save_rooms(fd) 726. int fd; 727. {  728.  	short i;  729. 730. 	/* First, write the number of rooms */ 731. 	bwrite(fd, (genericptr_t) &nroom, sizeof(nroom)); 732. 	for(i=0; insubrooms; i++) { 745. 		r->sbrooms[i] = &subrooms[nsubroom]; 746. 		rest_room(fd, &subrooms[nsubroom++]); 747. 	}  748.  }  749.   750.  /*  751.   * rest_rooms : That's for restoring rooms. Read the rooms structure from 752.  * the disk. 753.  */  754.   755.  void 756. rest_rooms(fd) 757. int	fd; 758. {  759.  	short i;  760. 761. 	mread(fd, (genericptr_t) &nroom, sizeof(nroom)); 762. 	nsubroom = 0; 763. 	for(i = 0; i<nroom; i++) { 764. 	    rest_room(fd, &rooms[i]); 765. 	    rooms[i].resident = (struct monst *)0; 766. 	}  767.  	rooms[nroom].hx = -1;		/* restore ending flags */ 768. 	subrooms[nsubroom].hx = -1; 769. }  770.  #endif /* OVLB */ 771.  772.  /*mkroom.c*/