Source:NetHack 3.3.0/mklev.c

Below is the full text to mklev.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.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.3	99/04/22	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    /* #define DEBUG */	/* uncomment to enable code debugging */ 7.    8.    #ifdef DEBUG 9.   # ifdef WIZARD 10.  #define debugpline	if (wizard) pline 11.  # else 12.  #define debugpline	pline 13.  # endif 14.  #endif 15.   16.   /* for UNIX, Rand #def'd to (long)lrand48 or (long)random */ 17.  /* croom->lx etc are schar (width <= int), so % arith ensures that */ 18.  /* conversion of result to int is reasonable */ 19.   20.    21.   STATIC_DCL void FDECL(mkfount,(int,struct mkroom *)); 22.  #ifdef SINKS 23.  STATIC_DCL void FDECL(mksink,(struct mkroom *)); 24.  #endif 25.  STATIC_DCL void FDECL(mkaltar,(struct mkroom *)); 26.  STATIC_DCL void FDECL(mkgrave,(struct mkroom *)); 27.  STATIC_DCL void NDECL(makevtele); 28.  STATIC_DCL void NDECL(clear_level_structures); 29.  STATIC_DCL void NDECL(makelevel); 30.  STATIC_DCL void NDECL(mineralize); 31.  STATIC_DCL boolean FDECL(bydoor,(XCHAR_P,XCHAR_P)); 32.  STATIC_DCL struct mkroom *FDECL(find_branch_room, (coord *)); 33.  STATIC_DCL struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P)); 34.  STATIC_DCL boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*)); 35.  STATIC_DCL void FDECL(makeniche,(int)); 36.  STATIC_DCL void NDECL(make_niches); 37.  STATIC_PTR int FDECL(do_comp,(const genericptr,const genericptr)); 38.  STATIC_DCL void FDECL(dosdoor,(XCHAR_P,XCHAR_P,struct mkroom *,int)); 39.  STATIC_DCL void FDECL(join,(int,int,BOOLEAN_P)); 40.  STATIC_DCL void FDECL(do_room_or_subroom, (struct mkroom *,int,int,int,int, 41.  				       BOOLEAN_P,SCHAR_P,BOOLEAN_P,BOOLEAN_P)); 42.  STATIC_DCL void NDECL(makerooms); 43.  STATIC_DCL void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P)); 44.  STATIC_DCL void FDECL(mkinvpos, (XCHAR_P,XCHAR_P,int)); 45.  STATIC_DCL void FDECL(mk_knox_portal, (XCHAR_P,XCHAR_P)); 46.   47.   #define create_vault	create_room(-1, -1, 2, 2, -1, -1, VAULT, TRUE) 48.  #define init_vault	vault_x = -1 49.  #define do_vault	(vault_x != -1) 50.  static xchar		vault_x, vault_y; 51.  boolean goldseen; 52.  static boolean made_branch;	/* used only during level creation */ 53.   54.   /* Args must be (const genericptr) so that qsort will always be happy. */ 55.    56.   STATIC_PTR int 57.  do_comp(vx,vy) 58.  const genericptr vx; 59.  const genericptr vy; 60.  {  61.   #ifdef LINT 62.  /* lint complains about possible pointer alignment problems, but we know 63.     that vx and vy are always properly aligned. Hence, the following 64.     bogus definition: 65.  */  66.   	return (vx == vy) ? 0 : -1; 67.   #else 68.  	register const struct mkroom *x, *y; 69.   70.   	x = (const struct mkroom *)vx; 71.  	y = (const struct mkroom *)vy; 72.  	if(x->lx < y->lx) return(-1); 73.  	return(x->lx > y->lx); 74.  #endif /* LINT */ 75.  }  76.    77.   STATIC_OVL void 78.  finddpos(cc, xl,yl,xh,yh) 79.  coord *cc; 80.  xchar xl,yl,xh,yh; 81.  {  82.   	register xchar x, y;  83. 84.  	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); 85.  	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); 86.  	if(okdoor(x, y)) 87.  		goto gotit; 88.   89.   	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 90.  		if(okdoor(x, y)) 91.  			goto gotit; 92.   93.   	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 94.  		if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR) 95.  			goto gotit; 96.  	/* cannot find something reasonable -- strange */ 97.  	x = xl; 98.  	y = yh; 99.  gotit: 100. 	cc->x = x;  101. cc->y = y; 102. return; 103. }  104.   105.  void 106. sort_rooms 107. {  108.  #if defined(SYSV) || defined(DGUX) 109. 	qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), do_comp); 110. #else 111. 	qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), do_comp); 112. #endif 113. }  114.   115.  STATIC_OVL void 116. do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room) 117.     register struct mkroom *croom; 118.     int lowx, lowy; 119.     register int hix, hiy; 120.     boolean lit; 121.     schar rtype; 122.     boolean special; 123.     boolean is_room; 124. {  125.  	register int x, y;  126. struct rm *lev; 127.  128.  	/* locations might bump level edges in wall-less rooms */ 129. 	/* add/subtract 1 to allow for edge locations */ 130. 	if(!lowx) lowx++; 131. 	if(!lowy) lowy++; 132. 	if(hix >= COLNO-1) hix = COLNO-2; 133. 	if(hiy >= ROWNO-1) hiy = ROWNO-2; 134.  135.  	if(lit) { 136. 		for(x = lowx-1; x <= hix+1; x++) { 137. 			lev = &levl[x][max(lowy-1,0)]; 138. 			for(y = lowy-1; y <= hiy+1; y++) 139. 				lev++->lit = 1; 140. 		}  141.  		croom->rlit = 1; 142. 	} else 143. 		croom->rlit = 0; 144.  145.  	croom->lx = lowx; 146. 	croom->hx = hix; 147. 	croom->ly = lowy; 148. 	croom->hy = hiy; 149. 	croom->rtype = rtype; 150. 	croom->doorct = 0; 151. 	/* if we're not making a vault, doorindex will still be 0 152. 	 * if we are, we'll have problems adding niches to the previous room 153. 	 * unless fdoor is at least doorindex 154. 	 */  155.  	croom->fdoor = doorindex; 156. 	croom->irregular = FALSE; 157.  158.  	croom->nsubrooms = 0; 159. 	croom->sbrooms[0] = (struct mkroom *) 0; 160. 	if (!special) { 161. 	    for(x = lowx-1; x <= hix+1; x++) 162. 		for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 163. 		    levl[x][y].typ = HWALL; 164. 		    levl[x][y].horizontal = 1;	/* For open/secret doors. */ 165.  		}  166.  	    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 167. 		for(y = lowy; y <= hiy; y++) { 168. 		    levl[x][y].typ = VWALL; 169. 		    levl[x][y].horizontal = 0;	/* For open/secret doors. */ 170.  		}  171.  	    for(x = lowx; x <= hix; x++) { 172. 		lev = &levl[x][lowy]; 173. 		for(y = lowy; y <= hiy; y++) 174. 		    lev++->typ = ROOM; 175. 	    }  176.  	    if (is_room) { 177. 		levl[lowx-1][lowy-1].typ = TLCORNER; 178. 		levl[hix+1][lowy-1].typ = TRCORNER; 179. 		levl[lowx-1][hiy+1].typ = BLCORNER; 180. 		levl[hix+1][hiy+1].typ = BRCORNER; 181. 	    } else {	/* a subroom */ 182. 		wallification(lowx-1, lowy-1, hix+1, hiy+1); 183. 	    }  184.  	}  185.  }  186.   187.   188.  void 189. add_room(lowx, lowy, hix, hiy, lit, rtype, special) 190. register int lowx, lowy, hix, hiy; 191. boolean lit; 192. schar rtype; 193. boolean special; 194. {  195.  	register struct mkroom *croom; 196.  197.  	croom = &rooms[nroom]; 198. 	do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,  199.  					    rtype, special, (boolean) TRUE); 200. 	croom++; 201. 	croom->hx = -1; 202. 	nroom++; 203. }  204.   205.  void 206. add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special) 207. struct mkroom *proom; 208. register int lowx, lowy, hix, hiy; 209. boolean lit; 210. schar rtype; 211. boolean special; 212. {  213.  	register struct mkroom *croom; 214.  215.  	croom = &subrooms[nsubroom]; 216. 	do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,  217.  					    rtype, special, (boolean) FALSE); 218. 	proom->sbrooms[proom->nsubrooms++] = croom; 219. 	croom++; 220. 	croom->hx = -1; 221. 	nsubroom++; 222. }  223.   224.  STATIC_OVL void 225. makerooms 226. {  227.  	boolean tried_vault = FALSE; 228.  229.  	/* make rooms until satisfied */ 230. 	/* rnd_rect will returns 0 if no more rects are available... */ 231.  	while(nroom < MAXNROFROOMS && rnd_rect) { 232. 		if(nroom >= (MAXNROFROOMS/6) && rn2(2) && !tried_vault) { 233. 			tried_vault = TRUE; 234. 			if (create_vault) { 235. 				vault_x = rooms[nroom].lx; 236. 				vault_y = rooms[nroom].ly; 237. 				rooms[nroom].hx = -1; 238. 			}  239.  		} else 240. 		    if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1)) 241. 			return; 242. 	}  243.  	return; 244. }  245.   246.  STATIC_OVL void 247. join(a,b,nxcor) 248. register int a, b;  249. boolean nxcor; 250. {  251.  	coord cc,tt, org, dest; 252. 	register xchar tx, ty, xx, yy; 253. 	register struct mkroom *croom, *troom; 254. 	register int dx, dy; 255.  256.  	croom = &rooms[a]; 257. 	troom = &rooms[b]; 258.  259.  	/* find positions cc and tt for doors in croom and troom 260. 	   and direction for a corridor between them */ 261.  262.  	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; 263. 	if(troom->lx > croom->hx) { 264. 		dx = 1; 265. 		dy = 0; 266. 		xx = croom->hx+1; 267. 		tx = troom->lx-1; 268. 		finddpos(&cc, xx, croom->ly, xx, croom->hy); 269. 		finddpos(&tt, tx, troom->ly, tx, troom->hy); 270. 	} else if(troom->hy < croom->ly) { 271. 		dy = -1; 272. 		dx = 0; 273. 		yy = croom->ly-1; 274. 		finddpos(&cc, croom->lx, yy, croom->hx, yy); 275. 		ty = troom->hy+1; 276. 		finddpos(&tt, troom->lx, ty, troom->hx, ty); 277. 	} else if(troom->hx < croom->lx) { 278. 		dx = -1; 279. 		dy = 0; 280. 		xx = croom->lx-1; 281. 		tx = troom->hx+1; 282. 		finddpos(&cc, xx, croom->ly, xx, croom->hy); 283. 		finddpos(&tt, tx, troom->ly, tx, troom->hy); 284. 	} else { 285. 		dy = 1; 286. 		dx = 0; 287. 		yy = croom->hy+1; 288. 		ty = troom->ly-1; 289. 		finddpos(&cc, croom->lx, yy, croom->hx, yy); 290. 		finddpos(&tt, troom->lx, ty, troom->hx, ty); 291. 	}  292.  	xx = cc.x;  293. yy = cc.y; 294. tx = tt.x - dx; 295. 	ty = tt.y - dy; 296. 	if(nxcor && levl[xx+dx][yy+dy].typ) 297. 		return; 298. 	if (okdoor(xx,yy) || !nxcor) 299. 	    dodoor(xx,yy,croom); 300.  301.  	org.x  = xx+dx; org.y  = yy+dy; 302. 	dest.x = tx; dest.y = ty; 303.  304.  	if (!dig_corridor(&org, &dest, nxcor, 305. 			level.flags.arboreal ? ROOM : CORR, STONE)) 306. 	    return; 307.  308.  	/* we succeeded in digging the corridor */ 309. 	if (okdoor(tt.x, tt.y) || !nxcor) 310. 	    dodoor(tt.x, tt.y, troom); 311.  312.  	if(smeq[a] < smeq[b]) 313. 		smeq[b] = smeq[a]; 314. 	else 315. 		smeq[a] = smeq[b]; 316. }  317.   318.  void 319. makecorridors 320. {  321.  	int a, b, i;  322. boolean any = TRUE; 323.  324.  	for(a = 0; a < nroom-1; a++) { 325. 		join(a, a+1, FALSE); 326. 		if(!rn2(50)) break; /* allow some randomness */ 327. 	}  328.  	for(a = 0; a < nroom-2; a++) 329. 	    if(smeq[a] != smeq[a+2]) 330. 		join(a, a+2, FALSE); 331. 	for(a = 0; any && a < nroom; a++) { 332. 	    any = FALSE; 333. 	    for(b = 0; b < nroom; b++) 334. 		if(smeq[a] != smeq[b]) { 335. 		    join(a, b, FALSE); 336. 		    any = TRUE; 337. 		}  338.  	}  339.  	if(nroom > 2) 340. 	    for(i = rn2(nroom) + 4; i; i--) { 341. 		a = rn2(nroom); 342. 		b = rn2(nroom-2); 343. 		if(b >= a) b += 2; 344. 		join(a, b, TRUE); 345. 	    }  346.  }  347.   348.  void 349. add_door(x,y,aroom) 350. register int x, y;  351. register struct mkroom *aroom; 352. {  353.  	register struct mkroom *broom; 354. 	register int tmp; 355.  356.  	aroom->doorct++; 357. 	broom = aroom+1; 358. 	if(broom->hx < 0) 359. 		tmp = doorindex; 360. 	else 361. 		for(tmp = doorindex; tmp > broom->fdoor; tmp--) 362. 			doors[tmp] = doors[tmp-1]; 363. 	doorindex++; 364. 	doors[tmp].x = x;  365. doors[tmp].y = y; 366. for(broom->hx >= 0; broom++) broom->fdoor++; 367. }  368.   369.  STATIC_OVL void 370. dosdoor(x,y,aroom,type) 371. register xchar x, y;  372. register struct mkroom *aroom; 373. register int type; 374. {  375.  	boolean shdoor = ((*in_rooms(x, y, SHOPBASE))? TRUE : FALSE); 376.  377.  	if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */ 378. 		type = DOOR; 379. 	levl[x][y].typ = type; 380. 	if(type == DOOR) { 381. 	    if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */ 382.  		if(!rn2(5)) 383. 		    levl[x][y].doormask = D_ISOPEN; 384. 		else if(!rn2(6)) 385. 		    levl[x][y].doormask = D_LOCKED; 386. 		else 387. 		    levl[x][y].doormask = D_CLOSED; 388.  389.  		if (levl[x][y].doormask != D_ISOPEN && !shdoor &&  390.  		    level_difficulty >= 5 && !rn2(25)) 391. 		    levl[x][y].doormask |= D_TRAPPED; 392. 	    } else 393. #ifdef STUPID 394. 		if (shdoor) 395. 			levl[x][y].doormask = D_ISOPEN; 396. 		else 397. 			levl[x][y].doormask = D_NODOOR; 398. #else 399. 		levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR); 400. #endif 401. 	    if(levl[x][y].doormask & D_TRAPPED) { 402. 		struct monst *mtmp; 403.  404.  		if (level_difficulty >= 9 && !rn2(5) &&  405.  		   !((mvitals[PM_SMALL_MIMIC].mvflags & G_GONE) && 406. 		     (mvitals[PM_LARGE_MIMIC].mvflags & G_GONE) && 407. 		     (mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) { 408. 		    /* make a mimic instead */ 409. 		    levl[x][y].doormask = D_NODOOR; 410. 		    mtmp = makemon(mkclass(S_MIMIC,0), x, y, NO_MM_FLAGS); 411. 		    if (mtmp) 412. 			set_mimic_sym(mtmp); 413. 		}  414.  	    }  415.  	    /* newsym(x,y); */ 416. 	} else { /* SDOOR */ 417. 		if(shdoor || !rn2(5))	levl[x][y].doormask = D_LOCKED; 418. 		else			levl[x][y].doormask = D_CLOSED; 419.  420.  		if(!shdoor && level_difficulty >= 4 && !rn2(20)) 421. 		    levl[x][y].doormask |= D_TRAPPED; 422. 	}  423.   424.  	add_door(x,y,aroom); 425. }  426.   427.  STATIC_OVL boolean 428. place_niche(aroom,dy,xx,yy) 429. register struct mkroom *aroom; 430. int *dy, *xx, *yy; 431. {  432.  	coord dd; 433.  434.  	if(rn2(2)) { 435. 	    *dy = 1; 436. 	    finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1); 437. 	} else { 438. 	    *dy = -1; 439. 	    finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1); 440. 	}  441.  	*xx = dd.x;  442. *yy = dd.y; 443. return((boolean)((isok(*xx,*yy+*dy) && levl[*xx][*yy+*dy].typ == STONE) 444. 	    && (isok(*xx,*yy-*dy) && !IS_POOL(levl[*xx][*yy-*dy].typ)  445.  				  && !IS_FURNITURE(levl[*xx][*yy-*dy].typ)))); 446. }  447.   448.  /* there should be one of these per trap, in the same order as trap.h */ 449. static NEARDATA const char *trap_engravings[TRAPNUM] = { 450. 			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 451. 			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 452. 			(char *)0, (char *)0, (char *)0, (char *)0, 453. 			/* 14..16: trapdoor, teleport, level-teleport */ 454. 			"Vlad was here", "ad aerarium", "ad aerarium", 455. 			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0, 456. 			(char *)0, 457. };  458.   459.  STATIC_OVL void 460. makeniche(trap_type) 461. int trap_type; 462. {  463.  	register struct mkroom *aroom; 464. 	register struct rm *rm; 465. 	register int vct = 8; 466. 	int dy, xx, yy; 467. 	register struct trap *ttmp; 468.  469.  	if(doorindex < DOORMAX) 470. 	  while(vct--) { 471. 	    aroom = &rooms[rn2(nroom)]; 472. 	    if(aroom->rtype != OROOM) continue;	/* not an ordinary room */ 473. 	    if(aroom->doorct == 1 && rn2(5)) continue; 474. 	    if(!place_niche(aroom,&dy,&xx,&yy)) continue; 475.  476.  	    rm = &levl[xx][yy+dy]; 477. 	    if(trap_type || !rn2(4)) { 478.  479.  		rm->typ = SCORR; 480. 		if(trap_type) { 481. 		    if((trap_type == HOLE || trap_type == TRAPDOOR)  482.  			&& !Can_fall_thru(&u.uz)) 483. 			trap_type = ROCKTRAP; 484. 		    ttmp = maketrap(xx, yy+dy, trap_type); 485. 		    if (ttmp) { 486. 			ttmp->once = 1; 487. 			if (trap_engravings[trap_type]) { 488. 			    make_engr_at(xx, yy-dy,  489.  				     trap_engravings[trap_type], 0L, DUST); 490. 			    wipe_engr_at(xx, yy-dy, 5); /* age it a little */ 491. 			}  492.  		    }  493.  		}  494.  		dosdoor(xx, yy, aroom, SDOOR); 495. 	    } else { 496. 		rm->typ = CORR; 497. 		if(rn2(7)) 498. 		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); 499. 		else { 500. 		    if (!level.flags.noteleport) 501. 			(void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy, TRUE); 502. 		    if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE); 503. 		}  504.  	    }  505.  	    return; 506. 	}  507.  }  508.   509.  STATIC_OVL void 510. make_niches 511. {  512.  	register int ct = rnd((nroom>>1) + 1), dep = depth(&u.uz); 513.  514.  	boolean	ltptr = (!level.flags.noteleport && dep > 15), 515. 		vamp = (dep > 5 && dep < 25); 516.  517.  	while(ct--) { 518. 		if (ltptr && !rn2(6)) { 519. 			ltptr = FALSE; 520. 			makeniche(LEVEL_TELEP); 521. 		} else if (vamp && !rn2(6)) { 522. 			vamp = FALSE; 523. 			makeniche(TRAPDOOR); 524. 		} else	makeniche(NO_TRAP); 525. 	}  526.  }  527.   528.  STATIC_OVL void 529. makevtele 530. {  531.  	makeniche(TELEP_TRAP); 532. }  533.   534.  /* clear out various globals that keep information on the current level. 535.  * some of this is only necessary for some types of levels (maze, normal,  536.   * special) but it's easier to put it all in one place than make sure 537.  * each type initializes what it needs to separately. 538.  */  539.  STATIC_OVL void 540. clear_level_structures 541. {  542.  	static struct rm zerorm = { cmap_to_glyph(S_stone), 543. 						0, 0, 0, 0, 0, 0, 0, 0 };  544.  	register int x,y; 545. 	register struct rm *lev; 546.  547.  	for(x=0; x<COLNO; x++) { 548. 	    lev = &levl[x][0]; 549. 	    for(y=0; y<ROWNO; y++) { 550. 		*lev++ = zerorm; 551. #ifdef MICROPORT_BUG 552. 		level.objects[x][y] = (struct obj *)0; 553. 		level.monsters[x][y] = (struct monst *)0; 554. #endif 555. 	    }  556.  	}  557.  #ifndef MICROPORT_BUG 558. 	(void) memset((genericptr_t)level.objects, 0, sizeof(level.objects)); 559. 	(void) memset((genericptr_t)level.monsters, 0, sizeof(level.monsters)); 560. #endif 561. 	level.objlist = (struct obj *)0; 562. 	level.buriedobjlist = (struct obj *)0; 563. 	level.monlist = (struct monst *)0; 564. 	level.damagelist = (struct damage *)0; 565.  566.  	level.flags.nfountains = 0; 567. 	level.flags.nsinks = 0; 568. 	level.flags.has_shop = 0; 569. 	level.flags.has_vault = 0; 570. 	level.flags.has_zoo = 0; 571. 	level.flags.has_court = 0; 572. 	level.flags.has_morgue = level.flags.graveyard = 0; 573. 	level.flags.has_beehive = 0; 574. 	level.flags.has_barracks = 0; 575. 	level.flags.has_temple = 0; 576. 	level.flags.has_swamp = 0; 577. 	level.flags.noteleport = 0; 578. 	level.flags.hardfloor = 0; 579. 	level.flags.nommap = 0; 580. 	level.flags.hero_memory = 1; 581. 	level.flags.shortsighted = 0; 582. 	level.flags.arboreal = 0; 583. 	level.flags.is_maze_lev = 0; 584. 	level.flags.is_cavernous_lev = 0; 585.  586.  	nroom = 0; 587. 	rooms[0].hx = -1; 588. 	nsubroom = 0; 589. 	subrooms[0].hx = -1; 590. 	doorindex = 0; 591. 	init_rect; 592. 	init_vault; 593. 	xdnstair = ydnstair = xupstair = yupstair = 0; 594. 	sstairs.sx = sstairs.sy = 0; 595. 	xdnladder = ydnladder = xupladder = yupladder = 0; 596. 	made_branch = FALSE; 597. 	clear_regions; 598. }  599.   600.  STATIC_OVL void 601. makelevel 602. {  603.  	register struct mkroom *croom, *troom; 604. 	register int tryct; 605. 	register int x, y;  606. struct monst *tmonst;	/* always put a web with a spider */ 607. 	branch *branchp; 608. 	int room_threshold; 609.  610.  	if(wiz1_level.dlevel == 0) init_dungeons; 611. 	oinit;	/* assign level dependent obj probabilities */ 612. 	clear_level_structures; 613.  614.  	{  615.  	    register s_level *slev = Is_special(&u.uz); 616.  617.  	    /* check for special levels */ 618. #ifdef REINCARNATION 619. 	    if (slev && !Is_rogue_level(&u.uz)) 620. #else 621. 	    if (slev) 622. #endif 623. 	    {  624.  		    makemaz(slev->proto); 625. 		    return; 626. 	    } else if (dungeons[u.uz.dnum].proto[0]) { 627. 		    makemaz(""); 628. 		    return; 629. 	    } else if (In_mines(&u.uz)) { 630. 		    makemaz("minefill"); 631. 		    return; 632. 	    } else if (In_quest(&u.uz)) { 633. 		    char	fillname[9]; 634. 		    s_level	*loc_lev; 635.  636.  		    Sprintf(fillname, "%s-loca", urole.filecode); 637. 		    loc_lev = find_level(fillname); 638.  639.  		    Sprintf(fillname, "%s-fil", urole.filecode); 640. 		    Strcat(fillname,  641.  			   (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b"); 642. 		    makemaz(fillname); 643. 		    return; 644. 	    } else if(In_hell(&u.uz) ||  645.  		  (rn2(5) && u.uz.dnum == medusa_level.dnum 646. 			  && depth(&u.uz) > depth(&medusa_level))) { 647. 		    makemaz(""); 648. 		    return; 649. 	    }  650.  	}  651.   652.  	/* otherwise, fall through - it's a "regular" level. */ 653.   654.  #ifdef REINCARNATION 655. 	if (Is_rogue_level(&u.uz)) { 656. 		makeroguerooms; 657. 		makerogueghost; 658. 	} else 659. #endif 660. 		makerooms; 661. 	sort_rooms; 662.  663.  	/* construct stairs (up and down in different rooms if possible) */ 664. 	croom = &rooms[rn2(nroom)]; 665. 	if (!Is_botlevel(&u.uz)) 666. 	     mkstairs(somex(croom), somey(croom), 0, croom);	/* down */ 667. 	if (nroom > 1) { 668. 	    troom = croom; 669. 	    croom = &rooms[rn2(nroom-1)]; 670. 	    if (croom == troom) croom++; 671. 	}  672.   673.  	if (u.uz.dlevel != 1) { 674. 	    xchar sx, sy; 675. 	    do { 676. 		sx = somex(croom); 677. 		sy = somey(croom); 678. 	    } while(occupied(sx, sy)); 679. 	    mkstairs(sx, sy, 1, croom);	/* up */ 680. 	}  681.   682.  	branchp = Is_branchlev(&u.uz);	/* possible dungeon branch */ 683. 	room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed 684. 					     to allow a random special room */ 685. #ifdef REINCARNATION 686. 	if (Is_rogue_level(&u.uz)) goto skip0; 687. #endif 688. 	makecorridors; 689. 	make_niches; 690.  691.  	/* make a secret treasure vault, not connected to the rest */ 692. 	if(do_vault) { 693. 		xchar w,h; 694. #ifdef DEBUG 695. 		debugpline("trying to make a vault..."); 696. #endif 697. 		w = 1; 698. 		h = 1; 699. 		if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) { 700. 		    fill_vault: 701. 			add_room(vault_x, vault_y, vault_x+w,  702.  				 vault_y+h, TRUE, VAULT, FALSE); 703. 			level.flags.has_vault = 1; 704. 			++room_threshold; 705. 			fill_room(&rooms[nroom - 1], FALSE); 706. 			mk_knox_portal(vault_x+w, vault_y+h); 707. 			if(!level.flags.noteleport && !rn2(3)) makevtele; 708. 		} else if(rnd_rect && create_vault) { 709. 			vault_x = rooms[nroom].lx; 710. 			vault_y = rooms[nroom].ly; 711. 			if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) 712. 				goto fill_vault; 713. 			else 714. 				rooms[nroom].hx = -1; 715. 		}  716.  	}  717.   718.      {  719.  	register int u_depth = depth(&u.uz); 720.  721.  #ifdef WIZARD 722. 	if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else 723. #endif 724. 	if (u_depth > 1 &&  725.  	    u_depth < depth(&medusa_level) &&  726.  	    nroom >= room_threshold &&  727.  	    rn2(u_depth) < 3) mkroom(SHOPBASE); 728. 	else if (u_depth > 4 && !rn2(6)) mkroom(COURT); 729. 	else if (u_depth > 5 && !rn2(8) &&  730.  	   !(mvitals[PM_LEPRECHAUN].mvflags & G_GONE)) mkroom(LEPREHALL); 731. 	else if (u_depth > 6 && !rn2(7)) mkroom(ZOO); 732. 	else if (u_depth > 8 && !rn2(5)) mkroom(TEMPLE); 733. 	else if (u_depth > 9 && !rn2(5) &&  734.  	   !(mvitals[PM_KILLER_BEE].mvflags & G_GONE)) mkroom(BEEHIVE); 735. 	else if (u_depth > 11 && !rn2(6)) mkroom(MORGUE); 736. 	else if (u_depth > 12 && !rn2(8)) mkroom(ANTHOLE); 737. 	else if (u_depth > 14 && !rn2(4) &&  738.  	   !(mvitals[PM_SOLDIER].mvflags & G_GONE)) mkroom(BARRACKS); 739. 	else if (u_depth > 15 && !rn2(6)) mkroom(SWAMP); 740. 	else if (u_depth > 16 && !rn2(8) &&  741.  	   !(mvitals[PM_COCKATRICE].mvflags & G_GONE)) mkroom(COCKNEST); 742.     }  743.   744.  #ifdef REINCARNATION 745. skip0: 746. #endif 747. 	/* Place multi-dungeon branch. */ 748.  	place_branch(branchp, 0, 0); 749.  750.  	/* for each room: put things inside */ 751. 	for(croom = rooms; croom->hx > 0; croom++) { 752. 		if(croom->rtype != OROOM) continue; 753.  754.  		/* put a sleeping monster inside */ 755. 		/* Note: monster may be on the stairs. This cannot be 756. avoided: maybe the player fell through a trap door 757. 		   while a monster was on the stairs. Conclusion: 758. 		   we have to check for monsters on the stairs anyway. */ 759.   760.  		if(u.uhave.amulet || !rn2(3)) { 761. 		    x = somex(croom); y = somey(croom); 762. 		    tmonst = makemon((struct permonst *) 0, x,y,NO_MM_FLAGS); 763. 		    if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] &&  764.  			!is_pool(x,y)) 765. 			(void) maketrap (x,y,WEB); 766. 		}  767.  		/* put traps and mimics inside */ 768. 		goldseen = FALSE; 769. 		x = 8 - (level_difficulty/6); 770. 		if (x <= 1) x = 2; 771. 		while (!rn2(x)) 772. 		    mktrap(0,0,croom,(coord*)0); 773. 		if (!goldseen && !rn2(3)) 774. 		    (void) mkgold(0L, somex(croom), somey(croom)); 775. #ifdef REINCARNATION 776. 		if(Is_rogue_level(&u.uz)) goto skip_nonrogue; 777. #endif 778. 		if(!rn2(10)) mkfount(0,croom); 779. #ifdef SINKS 780. 		if(!rn2(60)) mksink(croom); 781. #endif 782. 		if(!rn2(60)) mkaltar(croom); 783. 		x = 80 - (depth(&u.uz) * 2); 784. 		if (x < 2) x = 2; 785. 		if(!rn2(x)) mkgrave(croom); 786.  787.  		/* put statues inside */ 788. 		if(!rn2(20)) 789. 		    (void) mkcorpstat(STATUE, (struct monst *)0,  790.  				      (struct permonst *)0,  791.  				      somex(croom), somey(croom), TRUE); 792. 		/* put box/chest inside; 793. 		 *  40% chance for at least 1 box, regardless of number 794. 		 *  of rooms; about 5 - 7.5% for 2 boxes, least likely 795. 		 *  when few rooms; chance for 3 or more is neglible. 796. 		 */  797.  		if(!rn2(nroom * 5 / 2)) 798. 		    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,  799.  				     somex(croom), somey(croom), TRUE); 800.  801.  		/* maybe make some graffiti */ 802. 		if(!rn2(27 + 3 * abs(depth(&u.uz)))) { 803. 		    char buf[BUFSZ]; 804. 		    const char *mesg = random_engraving(buf); 805. 		    if (mesg) { 806. 			do { 807. 			    x = somex(croom);  y = somey(croom); 808. 			} while(levl[x][y].typ != ROOM && !rn2(40)); 809. 			if (!(IS_POOL(levl[x][y].typ) || 810. 			      IS_FURNITURE(levl[x][y].typ))) 811. 			    make_engr_at(x, y, mesg, 0L, MARK); 812. 		    }  813.  		}  814.   815.  #ifdef REINCARNATION 816. 	skip_nonrogue: 817. #endif 818. 		if(!rn2(3)) { 819. 		    (void) mkobj_at(0, somex(croom), somey(croom), TRUE); 820. 		    tryct = 0; 821. 		    while(!rn2(5)) { 822. 			if(++tryct > 100) { 823. 			    impossible("tryct overflow4"); 824. 			    break; 825. 			}  826.  			(void) mkobj_at(0, somex(croom), somey(croom), TRUE); 827. 		    }  828.  		}  829.  	}  830.  }  831.   832.  /*  833.   *	Place deposits of minerals (gold and misc gems) in the stone 834.  *	surrounding the rooms on the map. 835.  *	Also place kelp in water. 836.  */  837.  STATIC_OVL void 838. mineralize 839. {  840.  	s_level *sp; 841. 	struct obj *otmp; 842. 	int goldprob, gemprob, x, y, cnt; 843.  844.   845.  	/* Place kelp, except on the plane of water */ 846. 	if (In_endgame(&u.uz)) return; 847. 	for (x = 2; x < (COLNO - 2); x++) 848. 	    for (y = 1; y < (ROWNO - 1); y++) 849. 	    	if ((levl[x][y].typ == POOL || levl[x][y].typ == MOAT) && !rn2(3)) 850. 	    	    (void)mksobj_at(KELP_FROND, x, y, TRUE); 851.  852.  	/* determine if it is even allowed; 853. 	   almost all special levels are excluded */ 854. 	if (In_hell(&u.uz) || In_V_tower(&u.uz) ||  855.  #ifdef REINCARNATION  856.  		Is_rogue_level(&u.uz) ||  857.  #endif  858.  		level.flags.arboreal ||  859.  		((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz) 860. 					&& (!In_mines(&u.uz) || sp->flags.town) 861. 	    )) return; 862.  863.  	/* basic level-related probabilities */ 864. 	goldprob = 20 + depth(&u.uz) / 3; 865. 	gemprob = goldprob / 4; 866.  867.  	/* mines have ***MORE*** goodies - otherwise why mine? */ 868.  	if (In_mines(&u.uz)) { 869. 	    goldprob *= 2; 870. 	    gemprob *= 3; 871. 	} else if (In_quest(&u.uz)) { 872. 	    goldprob /= 4; 873. 	    gemprob /= 6; 874. 	}  875.   876.  	/*  877.  	 * Seed rock areas with gold and/or gems. 878. 	 * We use fairly low level object handling to avoid unnecessary 879. 	 * overhead from placing things in the floor chain prior to burial. 880. 	 */  881.  	for (x = 2; x < (COLNO - 2); x++) 882. 	  for (y = 1; y < (ROWNO - 1); y++) 883. 	    if (levl[x][y+1].typ != STONE) {	 /*  spot not eligible */ 884. 		y += 2;		/* next two spots aren't eligible either */ 885. 	    } else if (levl[x][y].typ != STONE) { /* this spot not eligible */ 886. 		y += 1;		/* next spot isn't eligible either */ 887. 	    } else if (!(levl[x][y].wall_info & W_NONDIGGABLE) &&  888.  		  levl[x][y-1].typ   == STONE &&  889.  		  levl[x+1][y-1].typ == STONE && levl[x-1][y-1].typ == STONE &&  890.  		  levl[x+1][y].typ   == STONE && levl[x-1][y].typ   == STONE &&  891.  		  levl[x+1][y+1].typ == STONE && levl[x-1][y+1].typ == STONE) { 892. 		if (rn2(1000) < goldprob) { 893. 		    if ((otmp = mksobj(GOLD_PIECE, FALSE, FALSE)) != 0) { 894. 			otmp->ox = x,  otmp->oy = y;  895. otmp->quan = 1L + rnd(goldprob * 3); 896. 			otmp->owt = weight(otmp); 897. 			if (!rn2(3)) add_to_buried(otmp); 898. 			else place_object(otmp, x, y); 899. 		    }  900.  		}  901.  		if (rn2(1000) < gemprob) { 902. 		    for (cnt = rnd(2 + dunlev(&u.uz) / 3); cnt > 0; cnt--) 903. 			if ((otmp = mkobj(GEM_CLASS, FALSE)) != 0) { 904. 			    if (otmp->otyp == ROCK) { 905. 				dealloc_obj(otmp);	/* discard it */ 906. 			    } else { 907. 				otmp->ox = x,  otmp->oy = y;  908. if (!rn2(3)) add_to_buried(otmp); 909. 				else place_object(otmp, x, y); 910. 			    }  911.  		    }  912.  		}  913.  	    }  914.  }  915.   916.  void 917. mklev 918. {  919.  	struct mkroom *croom; 920.  921.  	if(getbones) return; 922. 	in_mklev = TRUE; 923. 	makelevel; 924. 	bound_digging; 925. 	mineralize; 926. 	in_mklev = FALSE; 927. 	/* has_morgue gets cleared once morgue is entered; graveyard stays 928. 	   set (graveyard might already be set even when has_morgue is clear  929.  	   [see fixup_special], so don't update it unconditionally) */ 930. 	if (level.flags.has_morgue) 931. 	    level.flags.graveyard = 1; 932. 	if (!level.flags.is_maze_lev) { 933. 	    for (croom = &rooms[0]; croom != &rooms[nroom]; croom++) 934. #ifdef SPECIALIZATION 935. 		topologize(croom, FALSE); 936. #else 937. 		topologize(croom); 938. #endif 939. 	}  940.  	set_wall_state; 941. }  942.   943.  void 944. #ifdef SPECIALIZATION 945. topologize(croom, do_ordinary) 946. register struct mkroom *croom; 947. boolean do_ordinary; 948. #else 949. topologize(croom) 950. register struct mkroom *croom; 951. #endif 952. {  953.  	register int x, y, roomno = (croom - rooms) + ROOMOFFSET; 954. 	register int lowx = croom->lx, lowy = croom->ly; 955. 	register int hix = croom->hx, hiy = croom->hy; 956. #ifdef SPECIALIZATION 957. 	register schar rtype = croom->rtype; 958. #endif 959. 	register int subindex, nsubrooms = croom->nsubrooms; 960.  961.  	/* skip the room if already done; i.e. a shop handled out of order */ 962. 	/* also skip if this is non-rectangular (it _must_ be done already) */ 963. 	if ((int) levl[lowx][lowy].roomno == roomno || croom->irregular) 964. 	    return; 965. #ifdef SPECIALIZATION 966. # ifdef REINCARNATION 967. 	if (Is_rogue_level(&u.uz)) 968. 	    do_ordinary = TRUE;		/* vision routine helper */ 969. # endif 970. 	if ((rtype != OROOM) || do_ordinary) 971. #endif 972. 	{  973.  	    /* do innards first */ 974. 	    for(x = lowx; x <= hix; x++) 975. 		for(y = lowy; y <= hiy; y++) 976. #ifdef SPECIALIZATION 977. 		    if (rtype == OROOM) 978. 			levl[x][y].roomno = NO_ROOM; 979. 		    else 980. #endif 981. 			levl[x][y].roomno = roomno; 982. 	    /* top and bottom edges */ 983. 	    for(x = lowx-1; x <= hix+1; x++) 984. 		for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 985. 		    levl[x][y].edge = 1; 986. 		    if (levl[x][y].roomno) 987. 			levl[x][y].roomno = SHARED; 988. 		    else 989. 			levl[x][y].roomno = roomno; 990. 		}  991.  	    /* sides */ 992. 	    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 993. 		for(y = lowy; y <= hiy; y++) { 994. 		    levl[x][y].edge = 1; 995. 		    if (levl[x][y].roomno) 996. 			levl[x][y].roomno = SHARED; 997. 		    else 998. 			levl[x][y].roomno = roomno; 999. 		}  1000. 	}  1001. 	/* subrooms */ 1002. 	for (subindex = 0; subindex < nsubrooms; subindex++) 1003. #ifdef SPECIALIZATION 1004. 		topologize(croom->sbrooms[subindex], (rtype != OROOM)); 1005. #else 1006. 		topologize(croom->sbrooms[subindex]); 1007. #endif 1008. } 1009.  1010. /* Find an unused room for a branch location. */ 1011. STATIC_OVL struct mkroom * 1012. find_branch_room(mp) 1013.    coord *mp; 1014. { 1015.     struct mkroom *croom = 0; 1016. 1017.     if (nroom == 0) { 1018. 	mazexy(mp);		/* already verifies location */ 1019.    } else { 1020. 	/* not perfect - there may be only one stairway */ 1021. 	if(nroom > 2) { 1022. 	   int tryct = 0; 1023. 1024. 	    do  1025. croom = &rooms[rn2(nroom)]; 1026. 	   while((croom == dnstairs_room || croom == upstairs_room || 1027. 		 croom->rtype != OROOM) && (++tryct < 100)); 1028. 	} else 1029. 	   croom = &rooms[rn2(nroom)]; 1030. 1031. 	do { 1032. 	   if (!somexy(croom, mp)) 1033. 		impossible("Can't place branch!"); 1034. 	} while(occupied(mp->x, mp->y) || 1035. 	    (levl[mp->x][mp->y].typ != CORR && levl[mp->x][mp->y].typ != ROOM)); 1036.    }  1037.     return croom; 1038. } 1039.  1040. /* Find the room for (x,y). Return null if not in a room. */ 1041. STATIC_OVL struct mkroom * 1042. pos_to_room(x, y) 1043. xchar x, y; 1044. { 1045.     int i;  1046. struct mkroom *curr; 1047. 1048.     for (curr = rooms, i = 0; i < nroom; curr++, i++) 1049. 	if (inside_room(curr, x, y)) return curr;; 1050.    return (struct mkroom *) 0; 1051. } 1052.  1053.  1054. /* If given a branch, randomly place a special stair or portal. */ 1055. void 1056. place_branch(br, x, y) 1057. branch *br;	/* branch to place */ 1058. xchar x, y;	/* location */ 1059. { 1060. 	coord	      m;  1061. d_level	     *dest; 1062. 	boolean	     make_stairs; 1063. 	struct mkroom *br_room; 1064. 1065. 	/*  1066. 	 * Return immediately if there is no branch to make or we have 1067. 	 * already made one. This routine can be called twice when 1068. 	 * a special level is loaded that specifies an SSTAIR location 1069. 	 * as a favored spot for a branch. 1070. 	 */ 1071. 	if (!br || made_branch) return; 1072. 1073. 	if (!x) {	/* find random coordinates for branch */ 1074. 	   br_room = find_branch_room(&m); 1075. 	   x = m.x;  1076. y = m.y; 1077. } else { 1078. 	   br_room = pos_to_room(x, y); 1079. 	} 1080.  1081. 	if (on_level(&br->end1, &u.uz)) { 1082. 	   /* we're on end1 */ 1083. 	   make_stairs = br->type != BR_NO_END1; 1084. 	   dest = &br->end2; 1085. 	} else { 1086. 	   /* we're on end2 */ 1087. 	   make_stairs = br->type != BR_NO_END2; 1088. 	   dest = &br->end1; 1089. 	} 1090.  1091. 	if (br->type == BR_PORTAL) { 1092. 	   mkportal(x, y, dest->dnum, dest->dlevel); 1093. 	} else if (make_stairs) { 1094. 	   sstairs.sx = x;  1095. sstairs.sy = y; 1096. sstairs.up = (char) on_level(&br->end1, &u.uz) ? 1097. 					   br->end1_up : !br->end1_up; 1098. 	   assign_level(&sstairs.tolev, dest); 1099. 	   sstairs_room = br_room; 1100. 1101. 	    levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN; 1102. 	   levl[x][y].typ = STAIRS; 1103. 	} 1104. 	/*  1105. 	 * Set made_branch to TRUE even if we didn't make a stairwell (i.e.  1106. 	 * make_stairs is false) since there is currently only one branch 1107. 	 * per level, if we failed once, we're going to fail again on the 1108. 	 * next call. 1109. 	 */ 1110. 	made_branch = TRUE; 1111. } 1112.  1113. STATIC_OVL boolean 1114. bydoor(x, y) 1115. register xchar x, y; 1116. { 1117. 	register int typ; 1118. 1119. 	if (isok(x+1, y)) { 1120. 		typ = levl[x+1][y].typ; 1121. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE; 1122. 	} 1123. 	if (isok(x-1, y)) { 1124. 		typ = levl[x-1][y].typ; 1125. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE; 1126. 	} 1127. 	if (isok(x, y+1)) { 1128. 		typ = levl[x][y+1].typ; 1129. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE; 1130. 	} 1131. 	if (isok(x, y-1)) { 1132. 		typ = levl[x][y-1].typ; 1133. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE; 1134. 	} 1135. 	return FALSE; 1136. } 1137.  1138. /* see whether it is allowable to create a door at [x,y] */ 1139. int 1140. okdoor(x,y) 1141. register xchar x, y; 1142. { 1143. 	register boolean near_door = bydoor(x, y); 1144. 1145. 	return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&  1146. 			doorindex < DOORMAX && !near_door); 1147. } 1148.  1149. void 1150. dodoor(x,y,aroom) 1151. register int x, y; 1152. register struct mkroom *aroom; 1153. { 1154. 	if(doorindex >= DOORMAX) { 1155. 		impossible("DOORMAX exceeded?"); 1156. 		return; 1157. 	} 1158.  1159. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); 1160. } 1161.  1162. boolean 1163. occupied(x, y) 1164. register xchar x, y; 1165. { 1166. 	return((boolean)(t_at(x, y)  1167. || IS_FURNITURE(levl[x][y].typ) 1168. 		|| is_lava(x,y) 1169. 		|| is_pool(x,y) 1170. 		|| invocation_pos(x,y) 1171. 		)); 1172. }  1173.  1174. /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */ 1175. /* if tm != null, make trap at that location */ 1176. void 1177. mktrap(num, mazeflag, croom, tm) 1178. register int num, mazeflag; 1179. register struct mkroom *croom; 1180. coord *tm; 1181. { 1182. 	register int kind; 1183. 	coord m; 1184. 1185. 	/* no traps in pools */ 1186. 	if (tm && is_pool(tm->x,tm->y)) return; 1187. 1188. 	if (num > 0 && num < TRAPNUM) { 1189. 	   kind = num; 1190. #ifdef REINCARNATION 1191. 	} else if (Is_rogue_level(&u.uz)) { 1192. 	   switch (rn2(7)) { 1193. 		default: kind = BEAR_TRAP; break; /* 0 */ 1194. 		case 1: kind = ARROW_TRAP; break; 1195. 		case 2: kind = DART_TRAP; break; 1196. 		case 3: kind = TRAPDOOR; break; 1197. 		case 4: kind = PIT; break; 1198. 		case 5: kind = SLP_GAS_TRAP; break; 1199. 		case 6: kind = RUST_TRAP; break; 1200. 	   }  1201. #endif 1202. 	} else if (Inhell && !rn2(5)) { 1203. 	   /* bias the frequency of fire traps in Gehennom */ 1204. 	   kind = FIRE_TRAP; 1205. 	} else { 1206. 	   unsigned lvl = level_difficulty; 1207. 1208. 	    do { 1209. 		kind = rnd(TRAPNUM-1); 1210. 		/* reject "too hard" traps */ 1211. 		switch (kind) { 1212. 		   case MAGIC_PORTAL: 1213. 			kind = NO_TRAP; break; 1214. 		   case ROLLING_BOULDER_TRAP: 1215. 		   case SLP_GAS_TRAP: 1216. 			if (lvl < 2) kind = NO_TRAP; break; 1217. 		   case LEVEL_TELEP: 1218. 			if (lvl < 5 || level.flags.noteleport) 1219. 			   kind = NO_TRAP; break; 1220. 		   case SPIKED_PIT: 1221. 			if (lvl < 5) kind = NO_TRAP; break; 1222. 		   case LANDMINE: 1223. 			if (lvl < 6) kind = NO_TRAP; break; 1224. 		   case WEB: 1225. 			if (lvl < 7) kind = NO_TRAP; break; 1226. 		   case STATUE_TRAP: 1227. 		   case POLY_TRAP: 1228. 			if (lvl < 8) kind = NO_TRAP; break; 1229. 		   case FIRE_TRAP: 1230. 			if (!Inhell) kind = NO_TRAP; break; 1231. 		   case TELEP_TRAP: 1232. 			if (level.flags.noteleport) kind = NO_TRAP; break; 1233. 		   case HOLE: 1234. 			/* make these much less often than other traps */ 1235. 			if (rn2(7)) kind = NO_TRAP; break; 1236. 		} 1237. 	    } while (kind == NO_TRAP); 1238. 	} 1239.  1240. 	if ((kind == TRAPDOOR || kind == HOLE) && !Can_fall_thru(&u.uz)) 1241. 		kind = ROCKTRAP; 1242. 1243. 	if (tm) 1244. 	   m = *tm; 1245. 	else { 1246. 	   register int tryct = 0; 1247. 	   boolean avoid_boulder = (kind == PIT || kind == SPIKED_PIT ||  1248. 				     kind == TRAPDOOR || kind == HOLE); 1249. 1250. 	    do { 1251. 		if (++tryct > 200) 1252. 		   return; 1253. 		if (mazeflag) 1254. 		   mazexy(&m); 1255. 		else if (!somexy(croom,&m)) 1256. 		   return; 1257. 	   } while (occupied(m.x, m.y) ||  1258. 			(avoid_boulder && sobj_at(BOULDER, m.x, m.y))); 1259. 	} 1260.  1261. 	(void) maketrap(m.x, m.y, kind); 1262. 	if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], 1263. 						m.x, m.y, NO_MM_FLAGS); 1264. } 1265.  1266. void 1267. mkstairs(x, y, up, croom) 1268. xchar x, y; 1269. char up; 1270. struct mkroom *croom; 1271. { 1272. 	if (!x) { 1273. 	   impossible("mkstairs:  bogus stair attempt at <%d,%d>", x, y); 1274. 	   return; 1275. 	} 1276.  1277. 	/*  1278. 	 * We can't make a regular stair off an end of the dungeon. This 1279. 	 * attempt can happen when a special level is placed at an end and 1280. 	 * has an up or down stair specified in its description file. 1281. 	 */ 1282. 	if ((dunlev(&u.uz) == 1 && up) ||  1283. 			(dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up)) 1284. 	   return; 1285. 1286. 	if(up) { 1287. 		xupstair = x; 1288. yupstair = y; 1289. upstairs_room = croom; 1290. 	} else { 1291. 		xdnstair = x; 1292. ydnstair = y; 1293. dnstairs_room = croom; 1294. 	} 1295.  1296. 	levl[x][y].typ = STAIRS; 1297. 	levl[x][y].ladder = up ? LA_UP : LA_DOWN; 1298. } 1299.  1300. STATIC_OVL 1301. void 1302. mkfount(mazeflag,croom) 1303. register int mazeflag; 1304. register struct mkroom *croom; 1305. { 1306. 	coord m;  1307. register int tryct = 0; 1308. 1309. 	do { 1310. 	   if(++tryct > 200) return; 1311. 	   if(mazeflag) 1312. 		mazexy(&m); 1313. 	   else 1314. 		if (!somexy(croom, &m)) 1315. 		   return; 1316. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y)); 1317. 1318. 	/* Put a fountain at m.x, m.y */ 1319. 	levl[m.x][m.y].typ = FOUNTAIN; 1320. 	/* Is it a "blessed" fountain? (affects drinking from fountain) */ 1321. 	if(!rn2(7)) levl[m.x][m.y].blessedftn = 1; 1322. 1323. 	level.flags.nfountains++; 1324. } 1325.  1326. #ifdef SINKS 1327. STATIC_OVL void 1328. mksink(croom) 1329. register struct mkroom *croom; 1330. { 1331. 	coord m;  1332. register int tryct = 0; 1333. 1334. 	do { 1335. 	   if(++tryct > 200) return; 1336. 	   if (!somexy(croom, &m)) 1337. 		return; 1338. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y)); 1339. 1340. 	/* Put a sink at m.x, m.y */ 1341. 	levl[m.x][m.y].typ = SINK; 1342. 1343. 	level.flags.nsinks++; 1344. } 1345. #endif /* SINKS */ 1346. 1347.  1348. STATIC_OVL void 1349. mkaltar(croom) 1350. register struct mkroom *croom; 1351. { 1352. 	coord m;  1353. register int tryct = 0; 1354. 	aligntyp al; 1355. 1356. 	if (croom->rtype != OROOM) return; 1357. 1358. 	do { 1359. 	   if(++tryct > 200) return; 1360. 	   if (!somexy(croom, &m)) 1361. 		return; 1362. 	} while (occupied(m.x, m.y) || bydoor(m.x, m.y)); 1363. 1364. 	/* Put an altar at m.x, m.y */ 1365. 	levl[m.x][m.y].typ = ALTAR; 1366. 1367. 	/* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */ 1368. 	al = rn2((int)A_LAWFUL+2) - 1; 1369. 	levl[m.x][m.y].altarmask = Align2amask( al ); 1370. } 1371.  1372. static void 1373. mkgrave(croom) 1374. struct mkroom *croom; 1375. { 1376. 	coord m;  1377. register int tryct = 0; 1378. 	register struct obj *otmp; 1379. 1380.  1381. 	if(croom->rtype != OROOM) return; 1382. 1383. 	do { 1384. 	   if(++tryct > 200) return; 1385. 	   if (!somexy(croom, &m)) 1386. 		return; 1387. 	} while (occupied(m.x, m.y) || bydoor(m.x, m.y)); 1388. 1389. 	/* Put a grave at m.x, m.y */ 1390. 	levl[m.x][m.y].typ = GRAVE; 1391. 1392. 	/* Possibly fill it with objects */ 1393. 	if (!rn2(3)) (void) mkgold(0L, m.x, m.y); 1394. 	for (tryct = rn2(5); tryct; tryct--) { 1395. 	   otmp = mkobj(RANDOM_CLASS, TRUE); 1396. 	   if (!otmp) return; 1397. 	   curse(otmp); 1398. 	   otmp->ox = m.x;  1399. otmp->oy = m.y; 1400. add_to_buried(otmp); 1401. 	} 1402.  1403. 	/* Leave a bell, in case we accidentally buried someone alive */ 1404. 	if (!rn2(25)) (void) mksobj_at(BELL, m.x, m.y, TRUE); 1405. 	return; 1406. } 1407.  1408.  1409. /* maze levels have slightly different constraints from normal levels */ 1410. #define x_maze_min 2 1411. #define y_maze_min 2 1412. /* 1413.  * Major level transmutation: add a set of stairs (to the Sanctum) after 1414. * an earthquake that leaves behind a a new topology, centered at inv_pos. 1415. * Assumes there are no rooms within the invocation area and that inv_pos 1416. * is not too close to the edge of the map. Also assume the hero can see, 1417. * which is guaranteed for normal play due to the fact that sight is needed 1418. * to read the Book of the Dead. 1419. */  1420. void 1421. mkinvokearea 1422. { 1423.     int dist; 1424.    xchar xmin = inv_pos.x, xmax = inv_pos.x;  1425. xchar ymin = inv_pos.y, ymax = inv_pos.y; 1426. register xchar i; 1427. 1428.    pline_The("floor shakes violently under you!"); 1429.    pline_The("walls around you begin to bend and crumble!"); 1430.    display_nhwindow(WIN_MESSAGE, TRUE); 1431. 1432.     mkinvpos(xmin, ymin, 0);		/* middle, before placing stairs */ 1433. 1434.     for(dist = 1; dist < 7; dist++) { 1435. 	xmin--; xmax++; 1436. 1437. 	/* top and bottom */ 1438. 	if(dist != 3) { /* the area is wider that it is high */ 1439. 	   ymin--; ymax++; 1440. 	   for(i = xmin+1; i < xmax; i++) { 1441. 		mkinvpos(i, ymin, dist); 1442. 		mkinvpos(i, ymax, dist); 1443. 	   }  1444. 	}  1445.  1446. 	/* left and right */ 1447. 	for(i = ymin; i <= ymax; i++) { 1448. 	   mkinvpos(xmin, i, dist); 1449. 	   mkinvpos(xmax, i, dist); 1450. 	} 1451.  1452. 	flush_screen(1);	/* make sure the new glyphs shows up */ 1453. 	delay_output; 1454.    }  1455.  1456.     You("are standing at the top of a stairwell leading down!"); 1457.    mkstairs(u.ux, u.uy, 0, (struct mkroom *)0); /* down */ 1458.    newsym(u.ux, u.uy); 1459.    vision_full_recalc = 1;	/* everything changed */ 1460. } 1461.  1462. /* Change level topology. Boulders in the vicinity are eliminated. 1463. * Temporarily overrides vision in the name of a nice effect. 1464. */  1465. STATIC_OVL void 1466. mkinvpos(x,y,dist) 1467. xchar x,y; 1468. int dist; 1469. { 1470.     struct trap *ttmp; 1471.    struct obj *otmp; 1472.    boolean make_rocks; 1473.    register struct rm *lev = &levl[x][y]; 1474. 1475.     /* clip at existing map borders if necessary */ 1476.    if (!within_bounded_area(x, y, x_maze_min + 1, y_maze_min + 1, 1477. 				  x_maze_max - 1, y_maze_max - 1)) { 1478. 	/* only outermost 2 columns and/or rows may be truncated due to edge */ 1479. 	if (dist < (7 - 2)) 1480. 	   panic("mkinvpos: <%d,%d> (%d) off map edge!", x, y, dist); 1481. 	return; 1482.    }  1483.  1484.     /* clear traps */ 1485.    if ((ttmp = t_at(x,y)) != 0) deltrap(ttmp); 1486. 1487.     /* clear boulders; leave some rocks for non-{moat|trap} locations */ 1488.    make_rocks = (dist != 1 && dist != 4 && dist != 5) ? TRUE : FALSE; 1489.    while ((otmp = sobj_at(BOULDER, x, y)) != 0) { 1490. 	if (make_rocks) { 1491. 	   fracture_rock(otmp); 1492. 	   make_rocks = FALSE;		/* don't bother with more rocks */ 1493. 	} else { 1494. 	   obj_extract_self(otmp); 1495. 	   obfree(otmp, (struct obj *)0); 1496. 	} 1497.     }  1498.     unblock_point(x,y);	/* make sure vision knows this location is open */ 1499. 1500.     /* fake out saved state */ 1501.    lev->seenv = 0; 1502.    lev->doormask = 0; 1503.    if(dist < 6) lev->lit = TRUE; 1504.    lev->waslit = TRUE; 1505.    lev->horizontal = FALSE; 1506.    viz_array[y][x] = (dist < 6 ) ? 1507. 	(IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */ 1508. 	COULD_SEE; 1509. 1510.     switch(dist) { 1511.    case 1: /* fire traps */ 1512. 	if (is_pool(x,y)) break; 1513. 	lev->typ = ROOM; 1514. 	ttmp = maketrap(x, y, FIRE_TRAP); 1515. 	if (ttmp) ttmp->tseen = TRUE; 1516. 	break; 1517.    case 0: /* lit room locations */ 1518.    case 2: 1519.    case 3: 1520.    case 6: /* unlit room locations */ 1521. 	lev->typ = ROOM; 1522. 	break; 1523.    case 4: /* pools (aka a wide moat) */ 1524.    case 5: 1525. 	lev->typ = MOAT; 1526. 	/* No kelp! */ 1527. 	break; 1528.    default: 1529. 	impossible("mkinvpos called with dist %d", dist); 1530. 	break; 1531.    }  1532.  1533.     /* display new value of position; could have a monster/object on it */ 1534.    newsym(x,y); 1535. } 1536.  1537. /*  1538.  * The portal to Ludios is special. The entrance can only occur within a 1539. * vault in the main dungeon at a depth greater than 10. The Ludios branch 1540. * structure reflects this by having a bogus "source" dungeon:  the value 1541. * of n_dgns (thus, Is_branchlev will never find it). 1542. *  1543.  * Ludios will remain isolated until the branch is corrected by this function. 1544. */  1545. STATIC_OVL void 1546. mk_knox_portal(x, y) 1547. xchar x, y; 1548. { 1549. 	extern int n_dgns;		/* from dungeon.c */ 1550. 	d_level *source; 1551. 	branch *br; 1552. 	schar u_depth; 1553. 1554. 	br = dungeon_branch("Fort Ludios"); 1555. 	if (on_level(&knox_level, &br->end1)) { 1556. 	   source = &br->end2; 1557. 	} else { 1558. 	   /* disallow Knox branch on a level with one branch already */ 1559. 	   if(Is_branchlev(&u.uz)) 1560. 		return; 1561. 	   source = &br->end1; 1562. 	} 1563.  1564. 	/* Already set or 2/3 chance of deferring until a later level. */ 1565. 	if (source->dnum < n_dgns || (rn2(3) 1566. #ifdef WIZARD 1567. 				     && !wizard 1568. #endif 1569. 				     )) return; 1570. 1571. 	if (! (u.uz.dnum == oracle_level.dnum	    /* in main dungeon */ 1572. 		&& !at_dgn_entrance("The Quest")   /* but not Quest's entry */ 1573. 		&& (u_depth = depth(&u.uz)) > 10   /* beneath 10 */ 1574. 		&& u_depth < depth(&medusa_level))) /* and above Medusa */ 1575. 	   return; 1576. 1577. 	/* Adjust source to be current level and re-insert branch. */ 1578. 	*source = u.uz; 1579. 	insert_branch(br, TRUE); 1580. 1581. #ifdef DEBUG 1582. 	pline("Made knox portal."); 1583. #endif 1584. 	place_branch(br, x, y); 1585. } 1586.  1587. /*mklev.c*/