Source:NetHack 3.0.0/mklev.c

Below is the full text to mklev.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mklev.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)mklev.c	3.0	88/11/24 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   /* for UNIX, Rand #def'd to (long)lrand48 or (long)random */ 8.   /* croom->lx etc are schar (width <= int), so % arith ensures that */ 9.   /* conversion of result to int is reasonable */ 10.   11.   #ifdef SINKS 12.  static void mksink; 13.  #endif 14.  #ifdef ALTARS 15.  static void mkaltar; 16.  #endif 17.   18.   int 19.  somex(croom) 20.  register struct mkroom *croom; 21.  {  22.   	return rn2(croom->hx-croom->lx+1) + croom->lx; 23.  }  24.    25.   int 26.  somey(croom) 27.  register struct mkroom *croom; 28.  {  29.   	return rn2(croom->hy-croom->ly+1) + croom->ly; 30.  }  31.    32.   #define	XLIM	4	/* define minimum required space around a room */ 33.  #define	YLIM	3 34.  boolean secret;		/* TRUE while making a vault: increase [XY]LIM */ 35.  struct rm zerorm; 36.  schar nxcor; 37.  boolean goldseen; 38.   39.   /* Definitions used by makerooms and addrs */ 40.  #define	MAXRS	50	/* max lth of temp rectangle table - arbitrary */ 41.  struct rectangle { 42.  	xchar rlx,rly,rhx,rhy; 43.  } rs[MAXRS+1]; 44.  int rscnt,rsmax;	/* 0..rscnt-1: currently under consideration */ 45.  			/* rscnt..rsmax: discarded */ 46.   47.   static void 48.  addrsx(lx,ly,hx,hy,discarded) 49.  register int lx,ly,hx,hy; 50.  boolean discarded;		/* piece of a discarded area */ 51.  {  52.   	register struct rectangle *rsp; 53.   54.   	/* check inclusions */ 55.  	for(rsp = rs; rsp < &rs[rsmax]; rsp++) { 56.  		if(lx >= rsp->rlx && hx <= rsp->rhx &&  57.   		   ly >= rsp->rly && hy <= rsp->rhy) 58.  			return; 59.  	}  60.    61.   	/* make a new entry */ 62.  	if(rsmax >= MAXRS) { 63.  #ifdef WIZARD 64.  		if(wizard) pline("MAXRS may be too small."); 65.  #endif 66.  		return; 67.  	}  68.   	rsmax++; 69.  	if(!discarded) { 70.  		*rsp = rs[rscnt]; 71.  		rsp = &rs[rscnt]; 72.  		rscnt++; 73.  	}  74.   	rsp->rlx = lx; 75.  	rsp->rly = ly; 76.  	rsp->rhx = hx; 77.  	rsp->rhy = hy; 78.  }  79.    80.   static void 81.  addrs(lowx,lowy,hix,hiy) 82.  register int lowx,lowy,hix,hiy; 83.  {  84.   	register struct rectangle *rsp; 85.  	register int lx,ly,hx,hy,xlim,ylim; 86.  	boolean discarded; 87.   88.   	xlim = XLIM + secret; 89.  	ylim = YLIM + secret; 90.   91.   	/* walk down since rscnt and rsmax change */ 92.  	for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) { 93.   94.   		if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||  95.   		   (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy) 96.  			continue; 97.  		if((discarded = (rsp >= &rs[rscnt]))) { 98.  			*rsp = rs[--rsmax]; 99.  		} else { 100. 			rsmax--; 101. 			rscnt--; 102. 			*rsp = rs[rscnt]; 103. 			if(rscnt != rsmax) 104. 				rs[rscnt] = rs[rsmax]; 105. 		}  106.  		if(lowy - ly > 2*ylim + 4) 107. 			addrsx(lx,ly,hx,lowy-2,discarded); 108. 		if(lowx - lx > 2*xlim + 4) 109. 			addrsx(lx,ly,lowx-2,hy,discarded); 110. 		if(hy - hiy > 2*ylim + 4) 111. 			addrsx(lx,hiy+2,hx,hy,discarded); 112. 		if(hx - hix > 2*xlim + 4) 113. 			addrsx(hix+2,ly,hx,hy,discarded); 114. 	}  115.  }  116.   117.  static int 118. comp(x,y) 119. register struct mkroom *x,*y; 120. {  121.  	if(x->lx < y->lx) return(-1); 122. 	return(x->lx > y->lx); 123. }  124.   125.  static void 126. finddpos(cc, xl,yl,xh,yh) 127. coord	*cc; 128. xchar	xl,yl,xh,yh; 129. {  130.  	register xchar x, y;  131. 132. 	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); 133. 	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); 134. 	if(okdoor(x, y)) 135. 		goto gotit; 136.  137.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 138. 		if(okdoor(x, y)) 139. 			goto gotit; 140.  141.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 142. 		if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR) 143. 			goto gotit; 144. 	/* cannot find something reasonable -- strange */ 145. 	x = xl; 146. 	y = yh; 147. gotit: 148. 	cc->x = x;  149. cc->y = y; 150. return; 151. }  152.   153.  /* Only called from makerooms and makebigroom */ 154. static int 155. maker(lowx,ddx,lowy,ddy,lit) 156. schar lowx,ddx,lowy,ddy; 157. boolean lit; 158. {  159.  	register struct mkroom *croom; 160. 	register int x, y, hix = lowx+ddx, hiy = lowy+ddy; 161. 	register int xlim = XLIM + secret, ylim = YLIM + secret; 162.  163.  	if(nroom >= MAXNROFROOMS) return(0); 164. 	if(lowx < XLIM) lowx = XLIM; 165. 	if(lowy < YLIM) lowy = YLIM; 166. 	if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1; 167. 	if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1; 168. chk: 169. 	if(hix <= lowx || hiy <= lowy) return(0); 170.  171.  	/* check area around room (and make room smaller if necessary) */ 172. 	for(x = lowx - xlim; x <= hix + xlim; x++) { 173. 		for(y = lowy - ylim; y <= hiy + ylim; y++) { 174. 			if(levl[x][y].typ) { 175. #ifdef WIZARD 176. 			    if(wizard && !secret) 177. 				pline("Strange area [%d,%d] in maker.",x,y); 178. #endif 179. 				if(!rn2(3)) return(0); 180. 				if(x < lowx) 181. 					lowx = x+xlim+1; 182. 				else 183. 					hix = x-xlim-1; 184. 				if(y < lowy) 185. 					lowy = y+ylim+1; 186. 				else 187. 					hiy = y-ylim-1; 188. 				goto chk; 189. 			}  190.  		}  191.  	}  192.   193.  	croom = &rooms[nroom]; 194.  195.  	/* on low levels the room is lit (usually) */ 196. 	/* secret vaults are always lit */ 197. 	/* some other rooms may require lighting */ 198. 	if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) { 199. 		for(x = lowx-1; x <= hix+1; x++) 200. 			for(y = lowy-1; y <= hiy+1; y++) 201. 				levl[x][y].lit = 1; 202. 		croom->rlit = 1; 203. 	} else 204. 		croom->rlit = 0; 205. 	croom->lx = lowx; 206. 	croom->hx = hix; 207. 	croom->ly = lowy; 208. 	croom->hy = hiy; 209. 	croom->rtype = OROOM; 210. 	croom->doorct = 0; 211. 	/* if we're not making a vault, doorindex will still be 0 212. 	 * if we are, we'll have problems adding niches to the previous room 213. 	 * unless fdoor is at least doorindex 214. 	 */  215.  	croom->fdoor = doorindex; 216.  217.  	for(x = lowx-1; x <= hix+1; x++) 218. 	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 219. 		levl[x][y].typ = HWALL; 220. 		levl[x][y].scrsym = HWALL_SYM; 221. 	    }  222.  	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 223. 	    for(y = lowy; y <= hiy; y++) { 224. 		levl[x][y].typ = VWALL; 225. 		levl[x][y].scrsym = VWALL_SYM; 226. 	    }  227.  	for(x = lowx; x <= hix; x++) 228. 	    for(y = lowy; y <= hiy; y++) { 229. 		levl[x][y].typ = ROOM; 230. 		levl[x][y].scrsym = ROOM_SYM; 231. 	    }  232.  	levl[lowx-1][lowy-1].typ = TLCORNER; 233. 	levl[hix+1][lowy-1].typ = TRCORNER; 234. 	levl[lowx-1][hiy+1].typ = BLCORNER; 235. 	levl[hix+1][hiy+1].typ = BRCORNER; 236. 	levl[lowx-1][lowy-1].scrsym = TLCORN_SYM; 237. 	levl[hix+1][lowy-1].scrsym = TRCORN_SYM; 238. 	levl[lowx-1][hiy+1].scrsym = BLCORN_SYM; 239. 	levl[hix+1][hiy+1].scrsym = BRCORN_SYM; 240.  241.  	smeq[nroom] = nroom; 242. 	croom++; 243. 	croom->hx = -1; 244. 	nroom++; 245. 	return(1); 246. }  247.   248.  static int 249. makerooms { 250. register struct rectangle *rsp; 251. register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy; 252. int tryct = 0, xlim, ylim; 253.  254.  	/* init */ 255. 	xlim = XLIM + secret; 256. 	ylim = YLIM + secret; 257. 	if(nroom == 0) { 258. 		rsp = rs; 259. 		rsp->rlx = rsp->rly = 0; 260. 		rsp->rhx = COLNO-1; 261. 		rsp->rhy = ROWNO-1; 262. 		rsmax = 1; 263. 	}  264.  	rscnt = rsmax; 265.  266.  	/* make rooms until satisfied */ 267. 	while(rscnt > 0 && nroom < MAXNROFROOMS-1) { 268. 		if(!secret && nroom > (MAXNROFROOMS/4) &&  269.  		   !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom))) 270. 			return 0; 271.  272.  		/* pick a rectangle */ 273. 		rsp = &rs[rn2(rscnt)]; 274. 		hx = rsp->rhx; 275. 		hy = rsp->rhy; 276. 		lx = rsp->rlx; 277. 		ly = rsp->rly; 278.  279.  		/* find size of room */ 280. 		if(secret) 281. 			dx = dy = 1; 282. 		else { 283. 			dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8); 284. 			dy = 2 + rn2(4); 285. 			if(dx*dy > 50) 286. 				dy = 50/dx; 287. 		}  288.   289.  		/* look whether our room will fit */ 290. 		if(hx-lx < dx + (dx>>1) + 2*xlim ||  291.  		   hy-ly < dy + dy/3 + 2*ylim) { 292. 					/* no, too small */ 293. 					/* maybe we throw this area out */ 294. 			if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) { 295. 				rscnt--; 296. 				rs[rsmax] = *rsp; 297. 				*rsp = rs[rscnt]; 298. 				rs[rscnt] = rs[rsmax]; 299. 				tryct = 0; 300. 			} else 301. 				tryct++; 302. 			continue; 303. 		}  304.   305.  		lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1); 306. 		lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1); 307. 		hix = lowx + dx; 308. 		hiy = lowy + dy; 309.  310.  		if(maker(lowx, dx, lowy, dy, FALSE)) { 311. 			if(secret) return(1); 312. 			addrs(lowx-1, lowy-1, hix+1, hiy+1); 313. 			tryct = 0; 314. 		} else 315. 			if(tryct++ > 100) 316. 				break; 317. 	}  318.  	return(0);	/* failed to make vault - very strange */ 319. }  320.   321.  static void 322. join(a,b) 323. register int a, b;  324. { 325.  	coord cc,tt; 326. 	register int tx, ty, xx, yy; 327. 	register struct rm *crm; 328. 	register struct mkroom *croom, *troom; 329. 	register int dx, dy, dix, diy, cct; 330.  331.  	croom = &rooms[a]; 332. 	troom = &rooms[b]; 333.  334.  	/* find positions cc and tt for doors in croom and troom 335. 	   and direction for a corridor between them */ 336.  337.  	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; 338. 	if(troom->lx > croom->hx) { 339. 		dx = 1; 340. 		dy = 0; 341. 		xx = croom->hx+1; 342. 		tx = troom->lx-1; 343. 		finddpos(&cc, xx, croom->ly, xx, croom->hy); 344. 		finddpos(&tt, tx, troom->ly, tx, troom->hy); 345. 	} else if(troom->hy < croom->ly) { 346. 		dy = -1; 347. 		dx = 0; 348. 		yy = croom->ly-1; 349. 		finddpos(&cc, croom->lx, yy, croom->hx, yy); 350. 		ty = troom->hy+1; 351. 		finddpos(&tt, troom->lx, ty, troom->hx, ty); 352. 	} else if(troom->hx < croom->lx) { 353. 		dx = -1; 354. 		dy = 0; 355. 		xx = croom->lx-1; 356. 		tx = troom->hx+1; 357. 		finddpos(&cc, xx, croom->ly, xx, croom->hy); 358. 		finddpos(&tt, tx, troom->ly, tx, troom->hy); 359. 	} else { 360. 		dy = 1; 361. 		dx = 0; 362. 		yy = croom->hy+1; 363. 		ty = troom->ly-1; 364. 		finddpos(&cc, croom->lx, yy, croom->hx, yy); 365. 		finddpos(&tt, troom->lx, ty, troom->hx, ty); 366. 	}  367.  	xx = cc.x;  368. yy = cc.y; 369. tx = tt.x - dx; 370. 	ty = tt.y - dy; 371. 	if(nxcor && levl[xx+dx][yy+dy].typ) 372. 		return; 373. 	dodoor(xx,yy,croom); 374.  375.  	cct = 0; 376. 	while(xx != tx || yy != ty) { 377. 	    xx += dx; 378. 	    yy += dy; 379.  380.  	    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ 381. 	    if(cct++ > 500 || (nxcor && !rn2(35))) 382. 		return; 383.  384.  	    if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) 385. 		return;		/* impossible */ 386.  387.  	    crm = &levl[xx][yy]; 388. 	    if(!(crm->typ)) { 389. 		if(rn2(100)) { 390. 			crm->typ = CORR; 391. 			crm->scrsym = CORR_SYM; 392. 			if(nxcor && !rn2(50)) 393. 				(void) mksobj_at(BOULDER, xx, yy); 394. 		} else { 395. 			crm->typ = SCORR; 396. 			crm->scrsym = STONE_SYM; 397. 		}  398.  	    } else 399. 	    if(crm->typ != CORR && crm->typ != SCORR) { 400. 		/* strange ... */ 401.  		return; 402. 	    }  403.   404.  	    /* find next corridor position */ 405. 	    dix = abs(xx-tx); 406. 	    diy = abs(yy-ty); 407.  408.  	    /* do we have to change direction ? */ 409.  	    if(dy && dix > diy) { 410. 		register int ddx = (xx > tx) ? -1 : 1; 411.   412.  		crm = &levl[xx+ddx][yy]; 413. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 414. 		    dx = ddx; 415. 		    dy = 0; 416. 		    continue; 417. 		}  418.  	    } else if(dx && diy > dix) { 419. 		register int ddy = (yy > ty) ? -1 : 1; 420.   421.  		crm = &levl[xx][yy+ddy]; 422. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 423. 		    dy = ddy; 424. 		    dx = 0; 425. 		    continue; 426. 		}  427.  	    }  428.   429.  	    /* continue straight on? */ 430.  	    crm = &levl[xx+dx][yy+dy]; 431. 	    if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 432. 		continue; 433.  434.  	    /* no, what must we do now?? */ 435.  	    if(dx) { 436. 		dx = 0; 437. 		dy = (ty < yy) ? -1 : 1; 438.  		crm = &levl[xx+dx][yy+dy]; 439. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 440. 		    continue; 441. 		dy = -dy; 442. 		continue; 443. 	    } else { 444. 		dy = 0; 445. 		dx = (tx < xx) ? -1 : 1; 446.  		crm = &levl[xx+dx][yy+dy]; 447. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 448. 		    continue; 449. 		dx = -dx; 450. 		continue; 451. 	    }  452.  	}  453.   454.  	/* we succeeded in digging the corridor */ 455. 	dodoor(tt.x, tt.y, troom); 456.  457.  	if(smeq[a] < smeq[b]) 458. 		smeq[b] = smeq[a]; 459. 	else 460. 		smeq[a] = smeq[b]; 461. }  462.   463.  static void 464. makecorridors { 465. 	register int a, b;  466. 467. 	nxcor = 0; 468. 	for(a = 0; a < nroom-1; a++) 469. 		join(a, a+1); 470. 	for(a = 0; a < nroom-2; a++) 471. 	    if(smeq[a] != smeq[a+2]) 472. 		join(a, a+2); 473. 	for(a = 0; a < nroom; a++) 474. 	    for(b = 0; b < nroom; b++) 475. 		if(smeq[a] != smeq[b]) 476. 		    join(a, b); 477. 	if(nroom > 2) 478. 	    for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) { 479. 		a = rn2(nroom); 480. 		b = rn2(nroom-2); 481. 		if(b >= a) b += 2; 482. 		join(a, b); 483. 	    }  484.  }  485.   486.  static void 487. dosdoor(x,y,aroom,type) 488. register int x, y;  489. register struct mkroom *aroom; 490. register int type; 491. {  492.  	register struct mkroom *broom; 493. 	register int tmp; 494. 	boolean shdoor = in_shop(x, y); 495.  496.  	if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */ 497. 		type = DOOR; 498. 	levl[x][y].typ = type; 499. 	if(type == DOOR) { 500. 	    levl[x][y].scrsym = DOOR_SYM; 501. 	    if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */ 502.  		if(!rn2(5)) 503. 		    levl[x][y].doormask = D_ISOPEN; 504. 		else if(!rn2(4)) 505. 		    levl[x][y].doormask = D_LOCKED; 506. 		else 507. 		    levl[x][y].doormask = D_CLOSED; 508.  509.  		if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25)) 510. 		    levl[x][y].doormask |= D_TRAPPED; 511. 	    } else { 512. 		if(shdoor)	levl[x][y].doormask = D_ISOPEN; 513. 		else		levl[x][y].doormask = D_NODOOR; 514. 	    }  515.  	} else { /* SDOOR */ 516. 		if(shdoor || !rn2(5))	levl[x][y].doormask = D_LOCKED; 517. 		else			levl[x][y].doormask = D_CLOSED; 518.  519.  		if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED; 520. 	}  521.  	aroom->doorct++; 522. 	broom = aroom+1; 523. 	if(broom->hx < 0) tmp = doorindex; else 524. 	for(tmp = doorindex; tmp > broom->fdoor; tmp--) 525. 		doors[tmp] = doors[tmp-1]; 526. 	doorindex++; 527. 	doors[tmp].x = x;  528. doors[tmp].y = y; 529. for(broom->hx >= 0; broom++) broom->fdoor++; 530. }  531.   532.  static boolean 533. place_niche(aroom,dy,xx,yy) 534. register struct mkroom *aroom; 535. int *dy, *xx, *yy; 536. {  537.  	coord dd; 538.  539.  	if(rn2(2)) { 540. 	    *dy = 1; 541. 	    finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1); 542. 	} else { 543. 	    *dy = -1; 544. 	    finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1); 545. 	}  546.  	*xx = dd.x;  547. *yy = dd.y; 548. return(levl[*xx][(*yy)+(*dy)].typ == STONE); 549. }  550.   551.  #ifdef ORACLE 552. boolean 553. place_oracle(aroom,dy,xx,yy) 554. register struct mkroom *aroom; 555. int *dy, *xx, *yy; 556. {  557.  	if(!place_niche(aroom,dy,xx,yy)) return FALSE; 558.  559.  	dosdoor(*xx,*yy,aroom,DOOR); 560. 	levl[*xx][*yy].doormask = D_NODOOR; 561. 	return TRUE; 562. }  563.  #endif 564.  565.  /* there should be one of these per trap */ 566. const char *engravings[] = {	"", "", "", "", "", "", 567. 				"?la? ?as ?er?", "ad ae?ar um", 568. 				"", "", "", "" ,""  569.  			, "", "ad ae?ar um" 570. #ifdef SPELLS 571. 				,""  572.  #endif 573. 				,""  574.  #ifdef POLYSELF 575. 				,""  576.  #endif 577. 				,""  578.  				};  579.   580.  static void 581. makeniche(trap_type) 582. int trap_type; 583. {  584.  	register struct mkroom *aroom; 585. 	register struct rm *rm; 586. 	register int vct = 8; 587. 	int dy, xx, yy; 588. 	register struct trap *ttmp; 589.  590.  	if(doorindex < DOORMAX) 591. 	  while(vct--) { 592. 	    aroom = &rooms[rn2(nroom)]; 593. 	    if(aroom->rtype != OROOM) continue;	/* not an ordinary room */ 594. 	    if(aroom->doorct == 1 && rn2(5)) continue; 595. 	    if(!place_niche(aroom,&dy,&xx,&yy)) continue; 596.  597.  	    rm = &levl[xx][yy+dy]; 598. 	    if(trap_type || !rn2(4)) { 599.  600.  		rm->typ = SCORR; 601. 		rm->scrsym = STONE_SYM; 602. 		if(trap_type) { 603. 		    ttmp = maketrap(xx, yy+dy, trap_type); 604. 		    ttmp->once = 1; 605. 		    if (strlen(engravings[trap_type]) > 0) 606. 			make_engr_at(xx, yy-dy, engravings[trap_type]); 607. 		}  608.  		dosdoor(xx, yy, aroom, SDOOR); 609. 	    } else { 610. 		rm->typ = CORR; 611. 		rm->scrsym = CORR_SYM; 612. 		if(rn2(7)) 613. 		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); 614. 		else { 615. 		    (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy); 616. 		    if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy); 617. 		}  618.  	    }  619.  	    return; 620. 	}  621.  }  622.   623.  static void 624. make_niches 625. {  626.  	register int ct = rnd((nroom>>1) + 1); 627. 	boolean	ltptr = TRUE, 628. 		vamp = TRUE; 629.  630.  	while(ct--) { 631.  632.  		if(dlevel > 15 && !rn2(6) && ltptr) { 633.  634.  			ltptr = FALSE; 635. 			makeniche(LEVEL_TELEP); 636. 		} else if (dlevel > 5 && dlevel < 25  637.  			   && !rn2(6) && vamp) { 638.  639.  			vamp = FALSE; 640. 			makeniche(TRAPDOOR); 641. 		} else	makeniche(NO_TRAP); 642. 	}  643.  }  644.   645.  static void 646. makebigroom 647. {  648.  	register int x,y,n; 649. 	register struct mkroom *croom; 650. 	register struct monst *tmonst; 651.  652.  	/* make biggest possible room; make sure it's lit */ 653. 	(void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE); 654. 	croom = &rooms[0]; 655.  656.  	/* add extra monsters and goodies */ 657. 	n = 10 + rn2(15); 658. 	while (n--) { 659. 		x = somex(croom); 660. 		y = somey(croom); 661. 		tmonst = makemon((struct permonst *) 0,x,y); 662. 		if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER]) 663. 			(void) maketrap(x,y,WEB); 664. 		if (tmonst && rn2(2)) 665. 			tmonst->msleep = 1; 666. 	}  667.  	n = 6 + rn2(10); 668. 	while (n--) 669. 		(void) mkobj_at(0,somex(croom),somey(croom)); 670. }  671.   672.  static void 673. makevtele 674. {  675.  	makeniche(TELEP_TRAP); 676. }  677.   678.  #define rntwixt(L1,L2)	rn1((L2)-(L1),L1) 679.  680.  static void 681. init_levels 682. {  683.  #if defined(STRONGHOLD) && defined(MUSIC) 684. 	register int x;  685. #endif 686.  687.  #ifdef LINT	/* handle constant in conditional context */ 688. 	medusa_level = 0; 689. #else 690. 	medusa_level = rn1(3, HELLLEVEL - 5); 691. #endif /* LINT */ 692. #ifdef STRONGHOLD 693. 	stronghold_level = rn1(5, medusa_level)+1; 694. # ifdef MUSIC 695. 	for (x=0; x<5; x++) 696. 		tune[x] = 'A' + rn2(7); 697. 	tune[5] = 0; 698. # endif 699. 	/* The tower will be on 3 levels */ 700. 	tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1; 701. 	/* We don't want the wizard in Vlad's tower */ 702. 	do 703. 		wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1; 704. 	while (wiz_level >= tower_level && wiz_level <= tower_level + 2); 705. #else 706. 	wiz_level	 = rntwixt(medusa_level, MAXLEVEL)+1; 707. #endif /* STRONGHOLD /**/ 708. #ifdef WIZARD 709. 	if (!rn2(15) || wizard) 710. #else 711. 	if (!rn2(15)) 712. #endif 713. 		/* between the middle of the dungeon and the medusa level */ 714. 		bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level); 715. #ifdef REINCARNATION 716. # ifdef WIZARD 717. 	if (!rn2(3) || wizard) 718. # else 719. 	if (!rn2(3)) 720. # endif 721. 		rogue_level = rn1(5,10); 722. #endif 723. #ifdef ORACLE 724. 	oracle_level = rn1(4,5); 725. #endif 726. }  727.   728.  #undef rntwixt 729.  730.  static void 731. makelevel { 732. 	register struct mkroom *croom, *troom; 733. 	register unsigned int tryct; 734. 	register int x,y; 735. 	struct monst *tmonst;	/* always put a web with a spider */ 736.  737.  	nroom = 0; 738. 	doorindex = 0; 739. 	rooms[0].hx = -1;	/* in case we are in a maze */ 740.  741.  	for(x=0; x= stronghold_level || dlevel < 0  755.  #endif  756.  	    || (dlevel > medusa_level && rn2(5))  757.  	   ) { 758. 	    makemaz; 759. 	    return; 760. 	}  761.   762.  	/* construct the rooms */ 763. 	nroom = 0; 764. 	secret = FALSE; 765.  766.  #ifdef REINCARNATION 767. 	if (dlevel == rogue_level) { 768. 	    makeroguerooms; 769. 	    makerogueghost; 770. 	} else 771. #endif 772. 	if (dlevel == bigroom_level) 773. 	    makebigroom; 774. 	else 775. 	    (void) makerooms; 776.  777.  	/* construct stairs (up and down in different rooms if possible) */ 778. 	croom = &rooms[rn2(nroom)]; 779. 	xdnstair = somex(croom); 780. 	ydnstair = somey(croom); 781. 	levl[xdnstair][ydnstair].scrsym = DN_SYM; 782. 	levl[xdnstair][ydnstair].typ = STAIRS; 783. #ifdef MEDUSA 784. 	if (dlevel == medusa_level) { 785. 		struct monst *mtmp; 786.  787.  		if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair)) 788. 			mtmp->msleep = 1; 789. 		for (tryct = rn1(1,3); tryct; tryct--) { 790. 			x = somex(croom); y = somey(croom); 791. 			if (goodpos(x,y)) 792. 				(void) mk_tt_statue(x, y); 793. 		}  794.  	}  795.  #endif 796. 	if(nroom > 1) { 797. 		troom = croom; 798. 		croom = &rooms[rn2(nroom-1)]; 799. 		if(croom >= troom) croom++; 800. 	}  801.  	xupstair = somex(croom);    /* %% might be in the same place */ 802. 	yupstair = somey(croom); 803. 	levl[xupstair][yupstair].scrsym = UP_SYM; 804. 	levl[xupstair][yupstair].typ = STAIRS; 805. #ifdef STRONGHOLD 806. 	xdnladder = ydnladder = xupladder = yupladder = 0; 807. #endif 808. 	is_maze_lev = FALSE; 809.  810.  #ifdef SYSV 811. 	qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp); 812. #else 813. 	qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp); 814. #endif 815. #ifdef REINCARNATION 816. 	if (dlevel == rogue_level) { 817. 	   You("feel as though you were here in a previous lifetime."); 818. 	   return; 819. 	}  820.  #endif 821. 	makecorridors; 822. 	make_niches; 823.  824.  	/* make a secret treasure vault, not connected to the rest */ 825. 	if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) { 826.  827.  		troom = &rooms[nroom]; 828. 		secret = TRUE; 829. 		if(makerooms) { 830. 			troom->rtype = VAULT;		/* treasure vault */ 831. 			for(x = troom->lx; x <= troom->hx; x++) 832. 			for(y = troom->ly; y <= troom->hy; y++) 833. 				mkgold((long)(rnd(dlevel*100) + 50), x, y); 834. 			if(!rn2(3)) 835. 				makevtele; 836. 		}  837.  	}  838.   839.  #ifdef WIZARD 840. 	if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else 841. #endif 842. #ifdef ORACLE 843. 	if(dlevel == oracle_level) mkroom(DELPHI); 844. 	/*  It is possible that we find no good place to set up Delphi. 845. 	 *  It is also possible to get more than one Delphi using bones levels. 846. 	 *  The first is not a problem; the second is a minor nuisance. 847. 	 */  848.  	else 849. #endif 850. 	if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE); 851. 	else 852. #ifdef THRONES 853. 	if(dlevel > 4 && !rn2(6)) mkroom(COURT); 854. 	else 855. #endif 856. 	if(dlevel > 6 && !rn2(7)) mkroom(ZOO); 857. 	else 858. #ifdef ALTARS 859. 	if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE); 860. 	else 861. #endif 862. 	if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD)) 863. 		mkroom(BEEHIVE); 864. 	else 865. 	if(dlevel > 11 && !rn2(6)) mkroom(MORGUE); 866. 	else 867. #ifdef ARMY 868. 	if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD)) 869. 		mkroom(BARRACKS); 870. 	else 871. #endif 872. 	if(dlevel > 18 && !rn2(6)) mkroom(SWAMP); 873.  874.   875.  	/* for each room: put things inside */ 876. 	for(croom = rooms; croom->hx > 0; croom++) { 877. 		register boolean boxinlev = FALSE; 878.  879.  		if(croom->rtype != OROOM) continue; 880.  881.  		/* put a sleeping monster inside */ 882. 		/* Note: monster may be on the stairs. This cannot be 883. avoided: maybe the player fell through a trapdoor 884. 		   while a monster was on the stairs. Conclusion: 885. 		   we have to check for monsters on the stairs anyway. */ 886.   887.  		if(u.uhave_amulet || !rn2(3)) { 888. 		    x = somex(croom); y = somey(croom); 889. #ifdef REINCARNATION 890. 		    if (dlevel == rogue_level) 891. 			tmonst = makemon(roguemon, x, y); 892. 		    else 893. #endif 894. 		    tmonst = makemon((struct permonst *) 0, x,y); 895. 		    if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER]) 896. 			(void) maketrap (x,y,WEB); 897. 		}  898.  		/* put traps and mimics inside */ 899. 		goldseen = FALSE; 900. 		while(!rn2(8-(dlevel/6))) mktrap(0,0,croom); 901. 		if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom)); 902. #ifdef REINCARNATION 903. 		if (dlevel == rogue_level) goto skip_nonrogue; 904. #endif 905. #ifdef FOUNTAINS 906. 		if(!rn2(10)) mkfount(0,croom); 907. #endif 908. #ifdef SINKS 909. 		if(!rn2(60)) mksink(croom); 910. #endif 911. #ifdef ALTARS 912. 		if(!rn2(60)) mkaltar(croom); 913. #endif 914. 		/* put statues inside */ 915. #ifdef MEDUSA 916. 		if(!rn2(dlevel == medusa_level ? 1 : 20)) { 917.  			if (!rn2(dlevel == medusa_level ? 2 : 50)) 918.  				(void) mk_tt_statue(somex(croom), somey(croom)); 919. 			else { 920. 				struct obj *otmp = 921. 					mkstatue((struct permonst *)0,  922.  						somex(croom), somey(croom)); 923. 				if (dlevel == medusa_level && otmp) 924. 					otmp->spe = 0; 925. 				/* Medusa statues don't contain books */ 926. 			}  927.  		}  928.  #else 929. 		if(!rn2(20)) 930. 				(void) mkstatue((struct permonst *)0,  931.  						somex(croom), somey(croom)); 932. #endif 933.  934.  		/* put box/chest inside */ 935. 		if(!rn2(20) && !boxinlev) { 936.  937.  		    boxinlev = TRUE; 938. 		    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,  939.  				     somex(croom), somey(croom)); 940. 		}  941.   942.  #ifdef REINCARNATION 943. 	skip_nonrogue: 944. #endif 945. 		if(!rn2(3)) { 946. 			(void) mkobj_at(0, somex(croom), somey(croom)); 947. 			tryct = 0; 948. 			while(!rn2(5)) { 949. 				if(++tryct > 100){ 950. 					Printf("tryct overflow4\n"); 951. 					break; 952. 				}  953.  				(void) mkobj_at(0, somex(croom), somey(croom)); 954. 			}  955.  		}  956.  	}  957.  }  958.   959.  void 960. mklev 961. {  962.  	if(getbones) return; 963.  964.  	in_mklev = TRUE; 965. 	makelevel; 966. 	bound_digging; 967. 	in_mklev = FALSE; 968. }  969.   970.  static boolean 971. bydoor(x, y)  972. register xchar x, y; 973. { 974.  	register boolean tmp1, tmp2; 975.  976.  	/* break up large expression to help some compilers */ 977. 	tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||  978.  		IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR); 979. 	tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR ||  980.  		IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR); 981. 	return(tmp1 || tmp2); 982. }  983.   984.  /* see whether it is allowable to create a door at [x,y] */ 985. int 986. okdoor(x,y) 987. register xchar x, y;  988. { 989.  	register boolean near_door = bydoor(x, y); 990.  991.  	return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&  992.  	   		doorindex < DOORMAX && !near_door); 993. }  994.   995.  void 996. dodoor(x,y,aroom) 997. register int x, y;  998. register struct mkroom *aroom; 999. {  1000. 	if(doorindex >= DOORMAX) { 1001. 		impossible("DOORMAX exceeded?"); 1002. 		return; 1003. 	} 1004. 	if(!okdoor(x,y) && nxcor) 1005. 		return; 1006. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); 1007. } 1008.  1009. static boolean 1010. occupied(x, y) 1011. register xchar x, y; 1012. { 1013. 	return(t_at(x, y) || levl[x][y].typ == STAIRS  1014. #ifdef FOUNTAINS  1015. 		|| IS_FOUNTAIN(levl[x][y].typ)  1016. #endif  1017. #ifdef THRONES  1018. 		|| IS_THRONE(levl[x][y].typ)  1019. #endif  1020. #ifdef SINKS  1021. 		|| IS_SINK(levl[x][y].typ)  1022. #endif  1023. #ifdef ALTARS  1024. 		|| levl[x][y].typ == ALTAR  1025. #endif  1026. 		); 1027. } 1028.  1029. /* make a trap somewhere (in croom if mazeflag = 0) */ 1030. void 1031. mktrap(num, mazeflag, croom) 1032. register int num, mazeflag; 1033. register struct mkroom *croom; 1034. { 1035. 	register struct trap *ttmp; 1036. 	register int kind,nomonst,nomimic,nospider, 1037. #ifdef POLYSELF 1038. 		   nopoly, 1039. #endif 1040. 		   nospikes, nolevltp, 1041. 		   nolandmine, 1042. 		   tryct = 0; 1043. 1044. 	xchar mx,my; 1045. 1046. 	if(!num || num >= TRAPNUM) { 1047. 		nomonst = (dlevel < 4) ? 1 : 0; 1048. 		nolevltp = (dlevel < 5) ? 1 : 0; 1049. 		nospikes = (dlevel < 6) ? 1 : 0; 1050. 		nospider = (dlevel < 7) ? 1 : 0; 1051. #ifdef POLYSELF 1052. 		nopoly = (dlevel < 6) ? 1 : 0; 1053. #endif 1054. 		nolandmine = (dlevel < 5) ? 1 : 0; 1055. 		nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; 1056. 		if((mons[PM_SMALL_MIMIC].geno & G_GENOD) &&  1057. 		   (mons[PM_LARGE_MIMIC].geno & G_GENOD) &&  1058. 		   (mons[PM_GIANT_MIMIC].geno & G_GENOD)) 1059. 			nomimic = 1; 1060. 		if(mons[PM_GIANT_SPIDER].geno & G_GENOD) 1061. 			nospider = 1; 1062. 1063. 		do { 1064. #ifdef REINCARNATION 1065. 		   if (dlevel==rogue_level) { 1066. 			switch(rn2(7)) { 1067. 			    case 0: kind = BEAR_TRAP; break; 1068. 			    case 1: kind = ARROW_TRAP; break; 1069. 			    case 2: kind = DART_TRAP; break; 1070. 			    case 3: kind = TRAPDOOR; break; 1071. 			    case 4: kind = PIT; break; 1072. 			    case 5: kind = SLP_GAS_TRAP; break; 1073. 			    case 6: kind = RUST_TRAP; break; 1074. 			} 1075. 		    } else 1076. #endif 1077. 			   kind = rnd(TRAPNUM-1); 1078. 		   if((kind == MONST_TRAP && (nomonst && nomimic))  1079. 			|| ((kind == WEB) && nospider)  1080. 			|| (kind == SPIKED_PIT && nospikes)  1081. 			|| (kind == LEVEL_TELEP && nolevltp)  1082. #ifdef POLYSELF  1083. 			|| (kind == POLY_TRAP && nopoly)  1084. #endif  1085. 			|| (kind == LANDMINE && nolandmine)  1086. 			)  kind = NO_TRAP; 1087. 		} while(kind == NO_TRAP); 1088. 	} else kind = num; 1089. 1090. 	if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) { 1091. 		register struct monst *mtmp; 1092. 1093. 		do { 1094. 			if(++tryct > 200) return; 1095. 			/* note: fakedoor maybe on actual door */ 1096. 			if(rn2(2)){ 1097. 			   if(rn2(2))	mx = croom->hx+1; 1098. 			   else	mx = croom->lx-1; 1099. 			   my = somey(croom); 1100. 			} else { 1101. 			   if(rn2(2))	my = croom->hy+1; 1102. 			   else	my = croom->ly-1; 1103. 			   mx = somex(croom); 1104. 			} 1105. 		} while(levl[mx][my].mmask); 1106. 1107. 		if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) { 1108. 		   mtmp->mimic = 1; 1109. 		   mtmp->mappearance = DOOR_SYM; 1110. 		} 1111. 		return; 1112. 	} 1113.  1114. 	do { 1115. 		if(++tryct > 200) 1116. 			return; 1117. 		if(mazeflag){ 1118. 			coord mm; 1119. 			mazexy(&mm); 1120. 			mx = mm.x; 1121. my = mm.y; 1122. } else { 1123. 			mx = somex(croom); 1124. 			my = somey(croom); 1125. 		} 1126. 	} while(occupied(mx, my)); 1127. 1128. 	ttmp = maketrap(mx, my, kind); 1129. 	if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my); 1130. 	if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP) 1131. 		ttmp->tseen = 1; 1132. } 1133.  1134. #ifdef FOUNTAINS 1135. void 1136. mkfount(mazeflag,croom) 1137. register struct mkroom *croom; 1138. register int mazeflag; 1139. { 1140. 	register xchar mx,my; 1141. 	register int tryct = 0; 1142. 1143. 	do { 1144. 	   if(++tryct > 200) return; 1145. 	   if(mazeflag) { 1146. 		 coord mm; 1147. 		 mazexy(&mm); 1148. 		 mx = mm.x; 1149. my = mm.y; 1150. } else { 1151. 		 mx = somex(croom); 1152. 		 my = somey(croom); 1153. 	   }  1154. 	} while(occupied(mx, my) || bydoor(mx, my)); 1155. 1156. 	/* Put a fountain at mx, my */ 1157. 	levl[mx][my].typ = FOUNTAIN; 1158. 	levl[mx][my].scrsym = FOUNTAIN_SYM; 1159. 1160. 	fountsound++; 1161. } 1162. #endif /* FOUNTAINS /**/ 1163. 1164. #ifdef SINKS 1165. static void 1166. mksink(croom) 1167. register struct mkroom *croom; 1168. { 1169. 	register xchar mx,my; 1170. 	register int tryct = 0; 1171. 1172. 	do { 1173. 	   if(++tryct > 200) return; 1174. 	   mx = somex(croom); 1175. 	   my = somey(croom); 1176. 	} while(occupied(mx, my) || bydoor(mx, my)); 1177. 1178. 	/* Put a sink at mx, my */ 1179. 	levl[mx][my].typ = SINK; 1180. 	levl[mx][my].scrsym = SINK_SYM; 1181. 1182. 	sinksound++; 1183. } 1184. #endif /* SINKS /**/ 1185. 1186.  1187. #ifdef ALTARS 1188. static void 1189. mkaltar(croom) 1190. register struct mkroom *croom; 1191. { 1192. 	register xchar mx,my; 1193. 	register int tryct = 0; 1194. 1195. 	if(croom->rtype != OROOM) return; 1196. 1197. 	do { 1198. 	   if(++tryct > 200) return; 1199. 	   mx = somex(croom); 1200. 	   my = somey(croom); 1201. 	} while(occupied(mx, my) || bydoor(mx, my)); 1202. 1203. 	/* Put an altar at mx, my */ 1204. 	levl[mx][my].typ = ALTAR; 1205. 	levl[mx][my].scrsym = ALTAR_SYM; 1206. 	/* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */ 1207. 	levl[mx][my].altarmask = rn2((int)A_LAW+1); 1208. } 1209. #endif /* ALTARS /**/