Source:NetHack 3.2.0/mklev.c

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