Source:SLASH'EM 0.0.7E7F2/mkroom.c

Below is the full text to mkroom.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mkroom.c#line123 ]], for example.

The latest source code for vanilla NetHack is at 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(squadmon); 26.  STATIC_DCL struct permonst * NDECL(fungus); 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 REALZOO:   mkzoo(REALZOO); break; 60.  	case BADFOODSHOP: mkzoo(BADFOODSHOP); break; 61.  	case DRAGONLAIR: mkzoo(DRAGONLAIR); break; 62.  	case GIANTCOURT: mkzoo(GIANTCOURT); break; 63.  	case SWAMP:	mkswamp; break; 64.  	case TEMPLE:	mktemple; break; 65.  	case LEPREHALL:	mkzoo(LEPREHALL); break; 66.  	case COCKNEST:	mkzoo(COCKNEST); break; 67.  	case ANTHOLE:	mkzoo(ANTHOLE); break; 68.  	case LEMUREPIT: mkzoo(LEMUREPIT); break; 69.  	case MIGOHIVE:  mkzoo(MIGOHIVE); break; 70.  	case FUNGUSFARM: mkzoo(FUNGUSFARM); break; 71.  	default:	impossible("Tried to make a room of type %d.", roomtype); 72.      }  73.   }  74.    75.   STATIC_OVL void 76.  mkshop 77.  {  78.   	register struct mkroom *sroom; 79.  	int i = -1, j;  80. #ifdef WIZARD 81.  	char *ep = (char *)0;	/* (init == lint suppression) */ 82.   83.   	/* first determine shoptype */ 84.  	if(wizard){ 85.  #ifndef MAC 86.  		ep = nh_getenv("SHOPTYPE"); 87.  		if(ep){ 88.  			if(*ep == 'z' || *ep == 'Z'){ 89.  				mkzoo(ZOO); 90.  				return; 91.  			}  92.   			if(*ep == 'm' || *ep == 'M'){ 93.  				mkzoo(MORGUE); 94.  				return; 95.  			}  96.   			if(*ep == 'b' || *ep == 'B'){ 97.  				mkzoo(BEEHIVE); 98.  				return; 99.  			}  100.  			if (*ep == 'p' || *ep == 'P') { 101. 				mkzoo(LEMUREPIT); 102. 				return; 103. 			}  104.  			if (*ep == 'i' || *ep == 'I') { 105. 				mkzoo(MIGOHIVE); 106. 				return; 107. 			}  108.  			if (*ep == 'f' || *ep == 'F') { 109. 				mkzoo(FUNGUSFARM); 110. 				return; 111. 			}  112.  			if(*ep == 't' || *ep == 'T' || *ep == '\\'){ 113. 				mkzoo(COURT); 114. 				return; 115. 			}  116.  			if(*ep == 's' || *ep == 'S'){ 117. 				mkzoo(BARRACKS); 118. 				return; 119. 			}  120.  			if(*ep == 'a' || *ep == 'A'){ 121. 				mkzoo(ANTHOLE); 122. 				return; 123. 			}  124.  			if(*ep == 'c' || *ep == 'C'){ 125. 				mkzoo(COCKNEST); 126. 				return; 127. 			}  128.  			if(*ep == 'l' || *ep == 'L'){ 129. 				mkzoo(LEPREHALL); 130. 				return; 131. 			}  132.  			if(*ep == '_'){ 133. 				mktemple; 134. 				return; 135. 			}  136.  			if(*ep == '}'){ 137. 				mkswamp; 138. 				return; 139. 			}  140.  			j = -1; 141. 			for(i=0; shtypes[i].name; i++) 142. 				if(*ep == def_oc_syms[(int)shtypes[i].symb]) { 143. 					if (j < 0) j = i;  144. if (!strcmp(ep + 1, shtypes[i].name)) 145. 						break; 146. 				}  147.  			if(*ep == 'g' || *ep == 'G') 148. 				i = 0; 149. 			else 150. 				i = j;  151. } 152.  #endif 153. 	}  154.  #endif 155. 	for(sroom = &rooms[0]; ; sroom++){ 156. 		if(sroom->hx < 0) return; 157. 		if(sroom - rooms >= nroom) { 158. 			pline("rooms not closed by -1?"); 159. 			return; 160. 		}  161.  		if(sroom->rtype != OROOM) continue; 162. 		if(has_dnstairs(sroom) || has_upstairs(sroom)) 163. 			continue; 164. 		if(  165.  #ifdef WIZARD  166.  		   (wizard && ep && sroom->doorct != 0) ||  167.  #endif  168.  			sroom->doorct == 1) break; 169. 	}  170.  	if (!sroom->rlit) { 171. 		int x, y;  172. 173. 		for(x = sroom->lx - 1; x <= sroom->hx + 1; x++) 174. 		for(y = sroom->ly - 1; y <= sroom->hy + 1; y++) 175. 			levl[x][y].lit = 1; 176. 		sroom->rlit = 1; 177. 	}  178.   179.  	if(i < 0) {			/* shoptype not yet determined */ 180. 	    /* pick a shop type at random */ 181. 	    for (j = rnd(100), i = 0; (j -= shtypes[i].prob) > 0; i++) 182. 		continue; 183.  184.  	    /* big rooms cannot be wand or book shops, 185. 	     * - so make them general stores 186. 	     */  187.  	    if(isbig(sroom) && (shtypes[i].symb == WAND_CLASS 188. 				|| shtypes[i].symb == SPBOOK_CLASS)) i = 0; 189. 	}  190.  	sroom->rtype = SHOPBASE + i;  191. 192. 	/* set room bits before stocking the shop */ 193. #ifdef SPECIALIZATION 194. 	topologize(sroom, FALSE); /* doesn't matter - this is a special room */ 195. #else 196. 	topologize(sroom); 197. #endif 198.  199.  	/* stock the room with a shopkeeper and artifacts */ 200. 	stock_room(i, sroom); 201. }  202.   203.  STATIC_OVL struct mkroom * 204. pick_room(strict) 205. register boolean strict; 206. /* pick an unused room, preferably with only one door */ 207. {  208.  	register struct mkroom *sroom; 209. 	register int i = nroom; 210.  211.  	for(sroom = &rooms[rn2(nroom)]; i--; sroom++) { 212. 		if(sroom == &rooms[nroom]) 213. 			sroom = &rooms[0]; 214. 		if(sroom->hx < 0) 215. 			return (struct mkroom *)0; 216. 		if(sroom->rtype != OROOM)	continue; 217. 		if(!strict) { 218. 		    if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3))) 219. 			continue; 220. 		} else if(has_upstairs(sroom) || has_dnstairs(sroom)) 221. 			continue; 222. 		if(sroom->doorct == 1 || (!rn2(5) && !strict)  223.  #ifdef WIZARD  224.  						|| (wizard && !strict)  225.  #endif  226.  							) 227. 			return sroom; 228. 	}  229.  	return (struct mkroom *)0; 230. }  231.   232.  STATIC_OVL void 233. mkzoo(type) 234. int type; 235. {  236.  	register struct mkroom *sroom; 237.  238.  	if (type == BADFOODSHOP) { 239. 	   if ((sroom = pick_room(TRUE)) != 0) { 240. 		sroom->rtype = type; 241. 		fill_zoo(sroom); 242. 	   }  243.  	}  244.  	else if ((sroom = pick_room(FALSE)) != 0) { 245. 		sroom->rtype = type; 246. 		fill_zoo(sroom); 247. 	}  248.  }  249.   250.  void 251. fill_zoo(sroom) 252. struct mkroom *sroom; 253. {  254.  	struct monst *mon; 255. 	register int sx,sy,i; 256. 	int sh, tx, ty, goldlim, type = sroom->rtype; 257. 	int rmno = (sroom - rooms) + ROOMOFFSET; 258. 	coord mm; 259.  260.  #ifdef GCC_WARN 261. 	tx = ty = goldlim = 0; 262. #endif 263.  264.  	sh = sroom->fdoor; 265. 	switch(type) { 266. 	    case COURT: 267. 	    case GIANTCOURT: 268. 		if(level.flags.is_maze_lev) { 269. 		    for(tx = sroom->lx; tx <= sroom->hx; tx++) 270. 			for(ty = sroom->ly; ty <= sroom->hy; ty++) 271. 			    if(IS_THRONE(levl[tx][ty].typ)) 272. 				goto throne_placed; 273. 		}  274.   275.  		i = 100; 276. 		do {	/* don't place throne on top of stairs */ 277. 			(void) somexy(sroom, &mm); 278. 			tx = mm.x; ty = mm.y;  279. } while (occupied((xchar)tx, (xchar)ty) && --i > 0); 280. 	    throne_placed: 281. 		/* TODO: try to ensure the enthroned monster is an M2_PRINCE */ 282. 		break; 283. 	    case BEEHIVE: 284. 	    case MIGOHIVE: 285. 		tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2; 286. 		ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2; 287. 		if(sroom->irregular) { 288. 		    /* center might not be valid, so put queen elsewhere */ 289. 		    if ((int) levl[tx][ty].roomno != rmno ||  290.  			    levl[tx][ty].edge) { 291. 			(void) somexy(sroom, &mm); 292. 			tx = mm.x; ty = mm.y;  293. } 294.  		}  295.  		break; 296. 	    case ZOO: 297. 	    case LEPREHALL: 298. 		goldlim = 500 * level_difficulty; 299. 		break; 300. 	    case DRAGONLAIR: 301. 		goldlim = 1500 * level_difficulty; 302. 		break; 303. 	}  304.  	for(sx = sroom->lx; sx <= sroom->hx; sx++) 305. 	    for(sy = sroom->ly; sy <= sroom->hy; sy++) { 306. 		if(sroom->irregular) { 307. 		    if ((int) levl[sx][sy].roomno != rmno ||  308.  			  levl[sx][sy].edge ||  309.  			  (sroom->doorct && 310. 			   distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1)) 311. 			continue; 312. 		} else if(!SPACE_POS(levl[sx][sy].typ) ||  313.  			  (sroom->doorct && 314. 			   ((sx == sroom->lx && doors[sh].x == sx-1) ||  315.  			    (sx == sroom->hx && doors[sh].x == sx+1) ||  316.  			    (sy == sroom->ly && doors[sh].y == sy-1) ||  317.  			    (sy == sroom->hy && doors[sh].y == sy+1)))) 318. 		    continue; 319. 		/* don't place monster on explicitly placed throne */ 320. 		if(type == COURT && IS_THRONE(levl[sx][sy].typ)) 321. 		    continue; 322. 		mon = makemon(  323.  		    (type == COURT) ? courtmon :  324.  		    (type == BARRACKS) ? squadmon :  325.  		    (type == MORGUE) ? morguemon :  326.  		    (type == FUNGUSFARM) ? fungus :  327.  		    (type == BEEHIVE) ?  328.  			(sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 329. 			 &mons[PM_KILLER_BEE]) :  330.  		    (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] :  331.  		    (type == COCKNEST) ?  332.  		    	(rn2(4) ? &mons[PM_COCKATRICE] : 333. 		    	 &mons[PM_CHICKATRICE]) :  334.  		    (type == ANTHOLE) ? antholemon :  335.  		    (type == DRAGONLAIR) ? mkclass(S_DRAGON,0) :  336.  		    (type == LEMUREPIT)?  337.  		    	(!rn2(10)? &mons[PM_HORNED_DEVIL] : 338. 			           &mons[PM_LEMURE]) :  339.  		    (type == MIGOHIVE)?  340.  		      (sx == tx && sy == ty? &mons[PM_MIGO_QUEEN] : 341. 	              (rn2(2)? &mons[PM_MIGO_DRONE] : &mons[PM_MIGO_WARRIOR])) :  342.  		    (type == BADFOODSHOP) ? mkclass(S_BAD_FOOD,0) :  343.  		    (type == REALZOO) ? realzoomon :  344.  		    (type == GIANTCOURT) ? mkclass(S_GIANT,0) :  345.  		    (struct permonst *) 0,  346.  		   sx, sy, NO_MM_FLAGS); 347.  348.  		if(mon) { 349. 			mon->msleeping = 1; 350. 			if (type==COURT && mon->mpeaceful) { 351. 				mon->mpeaceful = 0; 352. 				set_malign(mon); 353. 			}  354.  		}  355.  		switch(type) { 356. 		    case ZOO: 357. 		    case DRAGONLAIR: 358. 		    case LEPREHALL: 359. 			if(sroom->doorct) 360. 			{  361.  			    int distval = dist2(sx,sy,doors[sh].x,doors[sh].y); 362. 			    i = sq(distval); 363. 			}  364.  			else 365. 			    i = goldlim; 366. 			if(i >= goldlim) i = 5*level_difficulty; 367. 			goldlim -= i;  368. (void) mkgold((long) rn1(i, 10), sx, sy); 369. 			break; 370. 		    case MORGUE: 371. 			if(!rn2(5)) 372. 			    (void) mk_tt_object(CORPSE, sx, sy); 373. 			if(!rn2(10))	/* lots of treasure buried with dead */ 374. 			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,  375.  					     sx, sy, TRUE, FALSE); 376. 			if (!rn2(5)) 377. 			    make_grave(sx, sy, (char *)0); 378. 			break; 379. 		    case BEEHIVE: 380. 			if(!rn2(3)) 381. 			    (void) mksobj_at(LUMP_OF_ROYAL_JELLY,  382.  					     sx, sy, TRUE, FALSE); 383. 			break; 384. 		    case FUNGUSFARM: 385. 			if (!rn2(3)) 386. 			    (void) mksobj_at(SLIME_MOLD, sx, sy, TRUE, FALSE); 387. 			break; 388. 		    case MIGOHIVE: 389. 			switch (rn2(10)) { 390. 			    case 9: 391. 				mksobj_at(DIAMOND, sx, sy, TRUE, FALSE); 392. 				break; 393. 			    case 8: 394. 				mksobj_at(RUBY, sx, sy, TRUE, FALSE); 395. 				break; 396. 			    case 7: 397. 			    case 6: 398. 				mksobj_at(AGATE, sx, sy, TRUE, FALSE); 399. 				break; 400. 			    case 5: 401. 			    case 4: 402. 				mksobj_at(FLUORITE, sx, sy, TRUE, FALSE); 403. 				break; 404. 			    default: 405. 				break; 406. 			}  407.  			break; 408. 		    case BARRACKS: 409. 			if(!rn2(20))	/* the payroll and some loot */ 410. 			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,  411.  					     sx, sy, TRUE, FALSE); 412. 			if (!rn2(5)) 413. 			    make_grave(sx, sy, (char *)0); 414. 			break; 415. 		    case COCKNEST: 416. 			if(!rn2(3)) { 417. 			    struct obj *sobj = mk_tt_object(STATUE, sx, sy); 418.  419.  			    if (sobj) { 420. 				for (i = rn2(5); i; i--) 421. 				    (void) add_to_container(sobj,  422.  						mkobj(RANDOM_CLASS, FALSE)); 423. 				sobj->owt = weight(sobj); 424. 			    }  425.  			}  426.  			break; 427. 		    case ANTHOLE: 428. 			if(!rn2(3)) 429. 			    (void) mkobj_at(FOOD_CLASS, sx, sy, FALSE); 430. 			break; 431. 		}  432.  	    }  433.  	switch (type) { 434. 	      case COURT: 435. 	      case GIANTCOURT: 436. 		{  437.  		  struct obj *chest; 438. 		  levl[tx][ty].typ = THRONE; 439. 		  (void) somexy(sroom, &mm); 440. 		  (void) mkgold((long) rn1(50 * level_difficulty,10), mm.x, mm.y); 441. 		  /* the royal coffers */ 442. 		  chest = mksobj_at(CHEST, mm.x, mm.y, TRUE, FALSE); 443. 		  chest->spe = 2; /* so it can be found later */ 444. 		  level.flags.has_court = 1; 445. 		  break; 446. 		}  447.  	      case BARRACKS: 448. 		  level.flags.has_barracks = 1; 449. 		  break; 450. 	      case REALZOO: 451. 	      case ZOO: 452. 		  level.flags.has_zoo = 1; 453. 		  break; 454. 	      case MORGUE: 455. 		  level.flags.has_morgue = 1; 456. 		  break; 457. 	      case SWAMP: 458. 		  level.flags.has_swamp = 1; 459. 		  break; 460. 	      case BEEHIVE: 461. 		  level.flags.has_beehive = 1; 462. 		  break; 463. 	      case LEMUREPIT: 464. 		  level.flags.has_lemurepit = 1; 465. 		  break; 466. 	      case MIGOHIVE: 467. 		  level.flags.has_migohive = 1; 468. 		  break; 469. 	      case FUNGUSFARM: 470. 		  level.flags.has_fungusfarm = 1; 471. 		  break; 472. 	}  473.  }  474.   475.  /* make a swarm of undead around mm */ 476. void 477. mkundead(mm, revive_corpses, mm_flags) 478. coord *mm; 479. boolean revive_corpses; 480. int mm_flags; 481. {  482.  	int cnt = (level_difficulty + 1)/10 + rnd(5); 483. 	struct permonst *mdat; 484. 	struct obj *otmp; 485. 	coord cc; 486.  487.  	while (cnt--) { 488. 	    mdat = morguemon; 489. 	    if (enexto(&cc, mm->x, mm->y, mdat) &&  490.  		    (!revive_corpses || 491. 		     !(otmp = sobj_at(CORPSE, cc.x, cc.y)) || 492. 		     !revive(otmp))) 493. 		(void) makemon(mdat, cc.x, cc.y, mm_flags); 494. 	}  495.  	level.flags.graveyard = TRUE;	/* reduced chance for undead corpse */ 496. }  497.   498.  STATIC_OVL struct permonst * 499. morguemon 500. {  501.  	register int i = rn2(100), hd = rn2(level_difficulty); 502.  503.  	if(hd > 10 && i < 10) 504. 		return((Inhell || In_endgame(&u.uz)) ? mkclass(S_DEMON,0) :  505.  						       &mons[ndemon(A_NONE)]); 506. 	if(hd > 8 && i > 85) 507. 		return(mkclass(S_VAMPIRE,0)); 508.  509.  	return((i < 20) ? &mons[PM_GHOST]  510.  			: (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE,0)); 511. }  512.   513.  struct permonst * 514. antholemon 515. {  516.  	int mtyp; 517.  518.  	/* Same monsters within a level, different ones between levels */ 519. 	switch ((level_difficulty + ((long)u.ubirthday)) % 4) { 520. 	default:	mtyp = PM_GIANT_ANT; break; 521. 	case 0:		mtyp = PM_SOLDIER_ANT; break; 522. 	case 1:		mtyp = PM_FIRE_ANT; break; 523. 	case 2:		mtyp = PM_SNOW_ANT; break; 524. 	}  525.  	return ((mvitals[mtyp].mvflags & G_GONE) ?  526.  			(struct permonst *)0 : &mons[mtyp]); 527. }  528.   529.   530.  STATIC_OVL struct permonst * 531. fungus 532. {  533.  	register int i, hd = level_difficulty, mtyp = 0; 534.  535.  	i = rn2(hd > 20 ? 17 : hd > 12 ? 14 : 12); 536.  537.  	switch (i) { 538. 	case 0: 539. 	case 1: mtyp = PM_LICHEN; 		break; 540. 	case 2: mtyp = PM_BROWN_MOLD;		break; 541. 	case 3: mtyp = PM_YELLOW_MOLD;		break; 542. 	case 4: mtyp = PM_GREEN_MOLD;		break; 543. 	case 5: mtyp = PM_RED_MOLD;		break; 544. 	case 6: mtyp = PM_SHRIEKER;		break; 545. 	case 7: mtyp = PM_VIOLET_FUNGUS;	break; 546. 	case 8: mtyp = PM_BLUE_JELLY;		break; 547. 	case 9: mtyp = PM_DISGUSTING_MOLD;	break; 548. 	case 10: mtyp = PM_BLACK_MOLD;		break; 549. 	case 11: mtyp = PM_GRAY_OOZE;		break; 550. 	/* Following only after level 12... */ 551.  	case 12: mtyp = PM_SPOTTED_JELLY;	break; 552. 	case 13: mtyp = PM_BROWN_PUDDING;	break; 553. 	/* Following only after level 20... */ 554.  	case 14: mtyp = PM_GREEN_SLIME;		break; 555. 	case 15: mtyp = PM_BLACK_PUDDING;	break; 556. 	case 16: mtyp = PM_OCHRE_JELLY;		break; 557. 	}  558.   559.  	return ((mvitals[mtyp].mvflags & G_GONE) ?  560.  			(struct permonst *)0 : &mons[mtyp]); 561. }  562.   563.  STATIC_OVL void 564. mkswamp	/* Michiel Huisjes & Fred de Wilde */ 565. {  566.  	register struct mkroom *sroom; 567. 	register int sx,sy,i,eelct = 0; 568.  569.  	for(i=0; i<5; i++) {		/* turn up to 5 rooms swampy */ 570. 		sroom = &rooms[rn2(nroom)]; 571. 		if(sroom->hx < 0 || sroom->rtype != OROOM ||  572.  		   has_upstairs(sroom) || has_dnstairs(sroom)) 573. 			continue; 574.  575.  		/* satisfied; make a swamp */ 576. 		sroom->rtype = SWAMP; 577. 		for(sx = sroom->lx; sx <= sroom->hx; sx++) 578. 		for(sy = sroom->ly; sy <= sroom->hy; sy++) 579. 		if(!OBJ_AT(sx, sy) &&  580.  		   !MON_AT(sx, sy) && !t_at(sx,sy) && !nexttodoor(sx,sy)) { 581. 		    if((sx+sy)%2) { 582. 			levl[sx][sy].typ = POOL; 583. 			if(!eelct || !rn2(4)) { 584. 			    /* mkclass won't do, as we might get kraken */ 585. 			    (void) makemon(rn2(5) ? &mons[PM_GIANT_EEL]  586.  						  : rn2(2) ? &mons[PM_PIRANHA]  587.  						  : &mons[PM_ELECTRIC_EEL],  588.  						sx, sy, NO_MM_FLAGS); 589. 			    eelct++; 590. 			}  591.  		    } else 592. 			if(!rn2(4))	/* swamps tend to be moldy */ 593. 			    (void) makemon(mkclass(S_FUNGUS,0),  594.  						sx, sy, NO_MM_FLAGS); 595. 		}  596.  		level.flags.has_swamp = 1; 597. 	}  598.  }  599.   600.  STATIC_OVL coord * 601. shrine_pos(roomno) 602. int roomno; 603. {  604.  	static coord buf; 605. 	struct mkroom *troom = &rooms[roomno - ROOMOFFSET]; 606.  607.  	buf.x = troom->lx + ((troom->hx - troom->lx) / 2); 608. 	buf.y = troom->ly + ((troom->hy - troom->ly) / 2); 609. 	return(&buf); 610. }  611.   612.  STATIC_OVL void 613. mktemple 614. {  615.  	register struct mkroom *sroom; 616. 	coord *shrine_spot; 617. 	register struct rm *lev; 618.  619.  	if(!(sroom = pick_room(TRUE))) return; 620.  621.  	/* set up Priest and shrine */ 622. 	sroom->rtype = TEMPLE; 623. 	/*  624.  	 * In temples, shrines are blessed altars 625. 	 * located in the center of the room 626. 	 */  627.  	shrine_spot = shrine_pos((sroom - rooms) + ROOMOFFSET); 628. 	lev = &levl[shrine_spot->x][shrine_spot->y]; 629. 	lev->typ = ALTAR; 630. 	lev->altarmask = induced_align(80); 631. 	priestini(&u.uz, sroom, shrine_spot->x, shrine_spot->y, FALSE); 632. 	lev->altarmask |= AM_SHRINE; 633. 	level.flags.has_temple = 1; 634. }  635.   636.  boolean 637. nexttodoor(sx,sy) 638. register int sx, sy; 639. {  640.  	register int dx, dy; 641. 	register struct rm *lev; 642. 	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) { 643. 		if(!isok(sx+dx, sy+dy)) continue; 644. 		if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||  645.  		    lev->typ == SDOOR) 646. 			return(TRUE); 647. 	}  648.  	return(FALSE); 649. }  650.   651.  boolean 652. has_dnstairs(sroom) 653. register struct mkroom *sroom; 654. {  655.  	if (sroom == dnstairs_room) 656. 		return TRUE; 657. 	if (sstairs.sx && !sstairs.up) 658. 		return((boolean)(sroom == sstairs_room)); 659. 	return FALSE; 660. }  661.   662.  boolean 663. has_upstairs(sroom) 664. register struct mkroom *sroom; 665. {  666.  	if (sroom == upstairs_room) 667. 		return TRUE; 668. 	if (sstairs.sx && sstairs.up) 669. 		return((boolean)(sroom == sstairs_room)); 670. 	return FALSE; 671. }  672.   673.  #endif /* OVLB */ 674. #ifdef OVL0 675.  676.  int 677. somex(croom) 678. register struct mkroom *croom; 679. {  680.  	return rn2(croom->hx-croom->lx+1) + croom->lx; 681. }  682.   683.  int 684. somey(croom) 685. register struct mkroom *croom; 686. {  687.  	return rn2(croom->hy-croom->ly+1) + croom->ly; 688. }  689.   690.  boolean 691. inside_room(croom, x, y)  692. struct mkroom *croom; 693. xchar x, y;  694. { 695.  	return((boolean)(x >= croom->lx-1 && x <= croom->hx+1 && 696. 		y >= croom->ly-1 && y <= croom->hy+1)); 697. }  698.   699.  boolean 700. somexy(croom, c)  701. struct mkroom *croom; 702. coord *c; 703. {  704.  	int try_cnt = 0; 705. 	int i;  706. 707. 	if (croom->irregular) { 708. 	    i = (croom - rooms) + ROOMOFFSET; 709.  710.  	    while(try_cnt++ < 100) { 711. 		c->x = somex(croom); 712. 		c->y = somey(croom); 713. 		if (!levl[c->x][c->y].edge &&  714.  			(int) levl[c->x][c->y].roomno == i)  715. return TRUE; 716. 	    }  717.  	    /* try harder; exhaustively search until one is found */ 718. 	    for(c->x = croom->lx; c->x <= croom->hx; c->x++) 719. 		for(c->y = croom->ly; c->y <= croom->hy; c->y++) 720. 		    if (!levl[c->x][c->y].edge &&  721.  			    (int) levl[c->x][c->y].roomno == i)  722. return TRUE; 723. 	    return FALSE; 724. 	}  725.   726.  	if (!croom->nsubrooms) { 727. 		c->x = somex(croom); 728. 		c->y = somey(croom); 729. 		return TRUE; 730. 	}  731.   732.  	/* Check that coords doesn't fall into a subroom or into a wall */ 733.  734.  	while(try_cnt++ < 100) { 735. 		c->x = somex(croom); 736. 		c->y = somey(croom); 737. 		if (IS_WALL(levl[c->x][c->y].typ)) 738. 		    continue; 739. 		for(i=0 ; insubrooms;i++) 740. 		    if(inside_room(croom->sbrooms[i], c->x, c->y)) 741. 			goto you_lose; 742. 		break; 743. you_lose:	; 744. 	}  745.  	if (try_cnt >= 100) 746. 	    return FALSE; 747. 	return TRUE; 748. }  749.   750.  /*  751.   * Search for a special room given its type (zoo, court, etc...) 752.  *	Special values : 753.  *		- ANY_SHOP 754.  *		- ANY_TYPE 755.  */  756.   757.  struct mkroom * 758. search_special(type) 759. schar type; 760. {  761.  	register struct mkroom *croom; 762.  763.  	for(croom = &rooms[0]; croom->hx >= 0; croom++) 764. 	    if((type == ANY_TYPE && croom->rtype != OROOM) ||  765.  	       (type == ANY_SHOP && croom->rtype >= SHOPBASE) ||  766.  	       croom->rtype == type) 767. 		return croom; 768. 	for(croom = &subrooms[0]; croom->hx >= 0; croom++) 769. 	    if((type == ANY_TYPE && croom->rtype != OROOM) ||  770.  	       (type == ANY_SHOP && croom->rtype >= SHOPBASE) ||  771.  	       croom->rtype == type) 772. 		return croom; 773. 	return (struct mkroom *) 0; 774. }  775.   776.  #endif /* OVL0 */ 777. #ifdef OVLB 778.  779.  struct permonst * 780. courtmon 781. {  782.  	int     i = rn2(60) + rn2(3*level_difficulty); 783. 	if (i > 200)            return(mkclass(S_DRAGON,0)); 784. 	else if (i > 130)       return(mkclass(S_GIANT,0)); 785. 	else if (i > 85)	return(mkclass(S_TROLL,0)); 786. 	else if (i > 75)	return(mkclass(S_CENTAUR,0)); 787. 	else if (i > 60)	return(mkclass(S_ORC,0)); 788. 	else if (i > 45)	return(&mons[PM_BUGBEAR]); 789. 	else if (i > 30)	return(&mons[PM_HOBGOBLIN]); 790. 	else if (i > 15)	return(mkclass(S_GNOME,0)); 791. 	else			return(mkclass(S_KOBOLD,0)); 792. }  793.   794.  struct permonst * 795. realzoomon 796. {  797.  	int     i = rn2(60) + rn2(3*level_difficulty); 798. 	if (i > 175)    return(&mons[PM_JUMBO_THE_ELEPHANT]); 799. 	else if (i > 115)       return(&mons[PM_MASTODON]); 800. 	else if (i > 85)        return(&mons[PM_PYTHON]); 801. 	else if (i > 70)        return(&mons[PM_MUMAK]); 802. 	else if (i > 55)        return(&mons[PM_TIGER]); 803. 	else if (i > 45)        return(&mons[PM_PANTHER]); 804. 	else if (i > 25)        return(&mons[PM_JAGUAR]); 805. 	else if (i > 15)        return(&mons[PM_APE]); 806. 	else                    return(&mons[PM_MONKEY]); 807. }  808.   809.  #define NSTYPES (PM_CAPTAIN - PM_SOLDIER + 1) 810.  811.  static struct { 812.     unsigned	pm; 813.     unsigned	prob; 814. } squadprob[NSTYPES] = { 815.     {PM_SOLDIER, 80}, {PM_SERGEANT, 15}, {PM_LIEUTENANT, 4}, {PM_CAPTAIN, 1} 816. };  817.   818.  STATIC_OVL struct permonst * 819. squadmon		/* return soldier types. */ 820.  {  821.  	int sel_prob, i, cpro, mndx; 822.  823.  	sel_prob = rnd(80+level_difficulty); 824.  825.  	cpro = 0; 826. 	for (i = 0; i < NSTYPES; i++) { 827. 	    cpro += squadprob[i].prob; 828. 	    if (cpro > sel_prob) { 829. 		mndx = squadprob[i].pm; 830. 		goto gotone; 831. 	    }  832.  	}  833.  	mndx = squadprob[rn2(NSTYPES)].pm; 834. gotone: 835. 	if (!(mvitals[mndx].mvflags & G_GONE)) return(&mons[mndx]); 836. 	else			    return((struct permonst *) 0); 837. }  838.   839.  /*  840.   * save_room : A recursive function that saves a room and its subrooms 841.  * (if any). 842.  */  843.   844.  STATIC_OVL void 845. save_room(fd, r)  846. int	fd; 847. struct mkroom *r; 848. {  849.  	short i;  850. /* 851.  	 * Well, I really should write only useful information instead 852. 	 * of writing the whole structure. That is I should not write 853. 	 * the subrooms pointers, but who cares ? 854. 	 */  855.  	bwrite(fd, (genericptr_t) r, sizeof(struct mkroom)); 856. 	for(i=0; insubrooms; i++) 857. 	    save_room(fd, r->sbrooms[i]); 858. }  859.   860.  /*  861.   * save_rooms : Save all the rooms on disk! 862.  */  863.   864.  void 865. save_rooms(fd) 866. int fd; 867. {  868.  	short i;  869. 870. 	/* First, write the number of rooms */ 871. 	bwrite(fd, (genericptr_t) &nroom, sizeof(nroom)); 872. 	for(i=0; insubrooms; i++) { 885. 		r->sbrooms[i] = &subrooms[nsubroom]; 886. 		rest_room(fd, &subrooms[nsubroom]); 887. 		subrooms[nsubroom++].resident = (struct monst *)0; 888. 	}  889.  }  890.   891.  /*  892.   * rest_rooms : That's for restoring rooms. Read the rooms structure from 893.  * the disk. 894.  */  895.   896.  void 897. rest_rooms(fd) 898. int	fd; 899. {  900.  	short i;  901. 902. 	mread(fd, (genericptr_t) &nroom, sizeof(nroom)); 903. 	nsubroom = 0; 904. 	for(i = 0; i<nroom; i++) { 905. 	    rest_room(fd, &rooms[i]); 906. 	    rooms[i].resident = (struct monst *)0; 907. 	}  908.  	rooms[nroom].hx = -1;		/* restore ending flags */ 909. 	subrooms[nsubroom].hx = -1; 910. }  911.  #endif /* OVLB */ 912.  913.  /*mkroom.c*/