Source:NetHack 3.1.0/mklev.c

Below is the full text to mklev.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1	92/10/10	*/ 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 boolean FDECL(bydoor,(XCHAR_P,XCHAR_P)); 30.  static struct mkroom *FDECL(find_branch_room, (coord *)); 31.  static struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P)); 32.  static boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*)); 33.  static void FDECL(makeniche,(int)); 34.  static void NDECL(make_niches); 35.  STATIC_PTR int FDECL(do_comp,(const genericptr,const genericptr)); 36.  static void FDECL(dosdoor,(XCHAR_P,XCHAR_P,struct mkroom *,int)); 37.  static void FDECL(join,(int,int,BOOLEAN_P)); 38.  static void FDECL(do_room_or_subroom, (struct mkroom *,int,int,int,int, 39.  				       BOOLEAN_P,SCHAR_P,BOOLEAN_P,BOOLEAN_P)); 40.  static void NDECL(makerooms); 41.  static void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P)); 42.  static void FDECL(mkinvpos, (XCHAR_P,XCHAR_P,int)); 43.  #ifdef MULDGN 44.  static void FDECL(mk_knox_portal, (XCHAR_P,XCHAR_P)); 45.  #endif 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 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 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 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 void 247. join(a,b,nxcor) 248. register int a, b;  249. boolean nxcor; 250. {  251.  	coord cc,tt, org, dest; 252. 	register int 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, CORR, STONE)) 305. 	    return; 306.  307.  	/* we succeeded in digging the corridor */ 308. 	if (okdoor(tt.x, tt.y) || !nxcor) 309. 	    dodoor(tt.x, tt.y, troom); 310.  311.  	if(smeq[a] < smeq[b]) 312. 		smeq[b] = smeq[a]; 313. 	else 314. 		smeq[a] = smeq[b]; 315. }  316.   317.  void 318. makecorridors 319. {  320.  	int a, b, i;  321. boolean any = TRUE; 322.  323.  	for(a = 0; a < nroom-1; a++) { 324. 		join(a, a+1, FALSE); 325. 		if(!rn2(50)) break; /* allow some randomness */ 326. 	}  327.  	for(a = 0; a < nroom-2; a++) 328. 	    if(smeq[a] != smeq[a+2]) 329. 		join(a, a+2, FALSE); 330. 	for(a = 0; any && a < nroom; a++) { 331. 	    any = FALSE; 332. 	    for(b = 0; b < nroom; b++) 333. 		if(smeq[a] != smeq[b]) { 334. 		    join(a, b, FALSE); 335. 		    any = TRUE; 336. 		}  337.  	}  338.  	if(nroom > 2) 339. 	    for(i = rn2(nroom) + 4; i; i--) { 340. 		a = rn2(nroom); 341. 		b = rn2(nroom-2); 342. 		if(b >= a) b += 2; 343. 		join(a, b, TRUE); 344. 	    }  345.  }  346.   347.  void 348. add_door(x,y,aroom) 349. register int x, y;  350. register struct mkroom *aroom; 351. {  352.  	register struct mkroom *broom; 353. 	register int tmp; 354.  355.  	aroom->doorct++; 356. 	broom = aroom+1; 357. 	if(broom->hx < 0) 358. 		tmp = doorindex; 359. 	else 360. 		for(tmp = doorindex; tmp > broom->fdoor; tmp--) 361. 			doors[tmp] = doors[tmp-1]; 362. 	doorindex++; 363. 	doors[tmp].x = x;  364. doors[tmp].y = y; 365. for(broom->hx >= 0; broom++) broom->fdoor++; 366. }  367.   368.  static void 369. dosdoor(x,y,aroom,type) 370. register xchar x, y;  371. register struct mkroom *aroom; 372. register int type; 373. {  374.  	boolean shdoor = ((*in_rooms(x, y, SHOPBASE))? TRUE : FALSE); 375.  376.  	if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */ 377. 		type = DOOR; 378. 	levl[x][y].typ = type; 379. 	if(type == DOOR) { 380. 	    if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */ 381.  		if(!rn2(5)) 382. 		    levl[x][y].doormask = D_ISOPEN; 383. 		else if(!rn2(6)) 384. 		    levl[x][y].doormask = D_LOCKED; 385. 		else 386. 		    levl[x][y].doormask = D_CLOSED; 387.  388.  		if (levl[x][y].doormask != D_ISOPEN && !shdoor && !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.  		   !((mons[PM_SMALL_MIMIC].geno & (G_GENOD | G_EXTINCT)) && 404. 		     (mons[PM_LARGE_MIMIC].geno & (G_GENOD | G_EXTINCT)) && 405. 		     (mons[PM_GIANT_MIMIC].geno & (G_GENOD | G_EXTINCT)))) { 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 && !rn2(20)) levl[x][y].doormask |= D_TRAPPED; 419. 	}  420.   421.  	add_door(x,y,aroom); 422. }  423.   424.  static boolean 425. place_niche(aroom,dy,xx,yy) 426. register struct mkroom *aroom; 427. int *dy, *xx, *yy; 428. {  429.  	coord dd; 430.  431.  	if(rn2(2)) { 432. 	    *dy = 1; 433. 	    finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1); 434. 	} else { 435. 	    *dy = -1; 436. 	    finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1); 437. 	}  438.  	*xx = dd.x;  439. *yy = dd.y; 440. return(isok(*xx,*yy+*dy) && levl[*xx][(*yy)+(*dy)].typ == STONE); 441. }  442.   443.  /* there should be one of these per trap */ 444. const char *trap_engravings[TRAPNUM] = { 445. 				"", "", "", "", "", "", "",  446.  				"", "", "", "", "", "",  447.  				"ad ae?ar um", "?la? ?as ?er?", "ad ae?ar um", 448. 				"", "", "", ""  449.  #ifdef POLYSELF 450. 				,""  451.  #endif 452. 				};  453.   454.  static void 455. makeniche(trap_type) 456. int trap_type; 457. {  458.  	register struct mkroom *aroom; 459. 	register struct rm *rm; 460. 	register int vct = 8; 461. 	int dy, xx, yy; 462. 	register struct trap *ttmp; 463.  464.  	if(doorindex < DOORMAX) 465. 	  while(vct--) { 466. 	    aroom = &rooms[rn2(nroom)]; 467. 	    if(aroom->rtype != OROOM) continue;	/* not an ordinary room */ 468. 	    if(aroom->doorct == 1 && rn2(5)) continue; 469. 	    if(!place_niche(aroom,&dy,&xx,&yy)) continue; 470.  471.  	    rm = &levl[xx][yy+dy]; 472. 	    if(trap_type || !rn2(4)) { 473.  474.  		rm->typ = SCORR; 475. 		if(trap_type) { 476. 		    if(trap_type == TRAPDOOR && !Can_fall_thru(&u.uz)) 477. 			trap_type = ROCKTRAP; 478. 		    ttmp = maketrap(xx, yy+dy, trap_type); 479. 		    ttmp->once = 1; 480. 		    if (*trap_engravings[trap_type]) 481. 			make_engr_at(xx, yy-dy, trap_engravings[trap_type], 0L, DUST); 482. 		}  483.  		dosdoor(xx, yy, aroom, SDOOR); 484. 	    } else { 485. 		rm->typ = CORR; 486. 		if(rn2(7)) 487. 		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); 488. 		else { 489. 		    (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy, TRUE); 490. 		    if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE); 491. 		}  492.  	    }  493.  	    return; 494. 	}  495.  }  496.   497.  static void 498. make_niches 499. {  500.  	register int ct = rnd((nroom>>1) + 1); 501. 	boolean	ltptr = TRUE, 502. 		vamp = TRUE; 503.  504.  	while(ct--) { 505.  506.  		if(depth(&u.uz) > 15 && !rn2(6) && ltptr) { 507. 			ltptr = FALSE; 508. 			makeniche(LEVEL_TELEP); 509. 		} else if(depth(&u.uz) > 5 && depth(&u.uz) < 25  510.  							&& !rn2(6) && vamp) { 511. 			vamp = FALSE; 512. 			makeniche(TRAPDOOR); 513. 		} else	makeniche(NO_TRAP); 514. 	}  515.  }  516.   517.  static void 518. makevtele 519. {  520.  	makeniche(TELEP_TRAP); 521. }  522.   523.  /* clear out various globals that keep information on the current level. 524.  * some of this is only necessary for some types of levels (maze, normal,  525.   * special) but it's easier to put it all in one place than make sure 526.  * each type initializes what it needs to separately. 527.  */  528.  static void 529. clear_level_structures 530. {  531.  	static struct rm zerorm = { cmap_to_glyph(S_stone), 532. 						0, 0, 0, 0, 0, 0, 0, 0 };  533.  	register int x,y; 534. 	register struct rm *lev; 535.  536.  	for(x=0; x<COLNO; x++) { 537. 	    lev = &levl[x][0]; 538. 	    for(y=0; y<ROWNO; y++) { 539. 		*lev++ = zerorm; 540. #ifdef MICROPORT_BUG 541. 		level.objects[x][y] = (struct obj *)0; 542. 		level.monsters[x][y] = (struct monst *)0; 543. #endif 544. 	    }  545.  	}  546.  #ifndef MICROPORT_BUG 547. 	(void) memset((genericptr_t)level.objects, 0, sizeof(level.objects)); 548. 	(void) memset((genericptr_t)level.monsters, 0, sizeof(level.monsters)); 549. #endif 550. 	level.flags.nfountains = 0; 551. 	level.flags.nsinks = 0; 552. 	level.flags.has_shop = 0; 553. 	level.flags.has_vault = 0; 554. 	level.flags.has_zoo = 0; 555. 	level.flags.has_court = 0; 556. 	level.flags.has_morgue = 0; 557. 	level.flags.has_beehive = 0; 558. #ifdef ARMY 559. 	level.flags.has_barracks = 0; 560. #endif 561. 	level.flags.has_temple = 0; 562. 	level.flags.has_swamp = 0; 563. 	level.flags.noteleport = 0; 564. 	level.flags.hardfloor = 0; 565. 	level.flags.nommap = 0; 566. 	level.flags.hero_memory = 1; 567. 	level.flags.shortsighted = 0; 568. 	level.flags.is_maze_lev = 0; 569. 	level.flags.is_cavernous_lev = 0; 570.  571.  	nroom = 0; 572. 	rooms[0].hx = -1; 573. 	nsubroom = 0; 574. 	doorindex = 0; 575. 	init_rect; 576. 	init_vault; 577. 	xdnstair = ydnstair = xupstair = yupstair = 0; 578. 	sstairs.sx = sstairs.sy = 0; 579. 	xdnladder = ydnladder = xupladder = yupladder = 0; 580. 	made_branch = FALSE; 581. }  582.   583.  static void 584. makelevel 585. {  586.  	register struct mkroom *croom, *troom; 587. 	register int tryct; 588. 	register int x, y;  589. struct monst *tmonst;	/* always put a web with a spider */ 590.  591.  	if(wiz1_level.dlevel == 0) init_dungeons; 592. 	oinit;	/* assign level dependent obj probabilities */ 593. 	clear_level_structures; 594.  595.  	{  596.  	    register s_level *slev = Is_special(&u.uz); 597.  598.  	    /* check for special levels */ 599. #ifdef REINCARNATION 600. 	    if (slev && !Is_rogue_level(&u.uz)) 601. #else 602. 	    if (slev) 603. #endif 604. 	    {  605.  		    makemaz(slev->proto); 606. 		    return; 607. 	    } else if (dungeons[u.uz.dnum].proto[0]) { 608. 		    makemaz(""); 609. 		    return; 610. #ifdef MULDGN 611. 	    } else if (In_mines(&u.uz)) { 612. 		    makemaz("minefill"); 613. 		    return; 614. 	    } else if (In_quest(&u.uz)) { 615. 		    char	fillname[9]; 616. 		    s_level	*loc_lev; 617.  618.  		    Sprintf(fillname, "%c-locate", pl_character[0]); 619. 		    loc_lev = find_level(fillname); 620.  621.  		    Sprintf(fillname, "%c-fill", pl_character[0]); 622. 		    Strcat(fillname,  623.  			   (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b"); 624. 		    makemaz(fillname); 625. 		    return; 626. #endif 627. 	    } else if(In_hell(&u.uz) ||  628.  		  (rn2(5) && u.uz.dnum == medusa_level.dnum 629. 			  && depth(&u.uz) > depth(&medusa_level))) { 630. 		    makemaz(""); 631. 		    return; 632. 	    }  633.  	}  634.   635.  	/* otherwise, fall through - it's a "regular" level. */ 636.   637.  #ifdef REINCARNATION 638. 	if (Is_rogue_level(&u.uz)) { 639. 		makeroguerooms; 640. 		makerogueghost; 641. 	} else 642. #endif 643. 		makerooms; 644. 	sort_rooms; 645.  646.  	/* construct stairs (up and down in different rooms if possible) */ 647. 	croom = &rooms[rn2(nroom)]; 648. 	if (!Is_botlevel(&u.uz)) 649. 	     mkstairs(somex(croom), somey(croom), 0, croom);	/* down */ 650. 	if (nroom > 1) { 651. 	    troom = croom; 652. 	    croom = &rooms[rn2(nroom-1)]; 653. 	    if (croom == troom) croom++; 654. 	}  655.   656.  	if (u.uz.dlevel != 1) { 657. 	    xchar sx, sy; 658. 	    do { 659. 		sx = somex(croom); 660. 		sy = somey(croom); 661. 	    } while(occupied(sx, sy)); 662. 	    mkstairs(sx, sy, 1, croom);	/* up */ 663. 	}  664.   665.  #ifdef REINCARNATION 666. 	if (Is_rogue_level(&u.uz)) goto skip0; 667. #endif 668. 	makecorridors; 669. 	make_niches; 670.  671.  	/* make a secret treasure vault, not connected to the rest */ 672. 	if(do_vault) { 673. 		xchar w,h; 674. #ifdef DEBUG 675. 		debugpline("trying to make a vault..."); 676. #endif 677. 		w = 1; 678. 		h = 1; 679. 		if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) { 680. 		    fill_vault: 681. 			add_room(vault_x, vault_y, vault_x+w,  682.  				 vault_y+h, TRUE, VAULT, FALSE); 683. 			level.flags.has_vault = 1; 684. 			fill_room(&rooms[nroom - 1], FALSE); 685. #ifdef MULDGN 686. 			mk_knox_portal(vault_x+w, vault_y+h); 687. #endif 688. 			if(!rn2(3)) makevtele; 689. 		} else if(rnd_rect && create_vault) { 690. 			vault_x = rooms[nroom].lx; 691. 			vault_y = rooms[nroom].ly; 692. 			if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) 693. 				goto fill_vault; 694. 			else 695. 				rooms[nroom].hx = -1; 696. 		}  697.  	}  698.   699.  #ifdef WIZARD 700. 	if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else 701. #endif 702. 	if(depth(&u.uz) > 1 &&  703.  	   depth(&u.uz) < depth(&medusa_level) &&  704.  	   rn2(depth(&u.uz)) < 3) mkroom(SHOPBASE); 705. 	else if(depth(&u.uz) > 4 && !rn2(6)) mkroom(COURT); 706. 	else if(depth(&u.uz) > 6 && !rn2(7)) mkroom(ZOO); 707. 	else if(depth(&u.uz) > 8 && !rn2(5)) mkroom(TEMPLE); 708. 	else if(depth(&u.uz) > 9 && !rn2(5) &&  709.  	   !(mons[PM_KILLER_BEE].geno & (G_GENOD | G_EXTINCT))) mkroom(BEEHIVE); 710. 	else if(depth(&u.uz) > 11 && !rn2(6)) mkroom(MORGUE); 711. 	else 712. #ifdef ARMY 713. 	if(depth(&u.uz) > 14 && !rn2(4) &&  714.  	   !(mons[PM_SOLDIER].geno & (G_GENOD | G_EXTINCT))) mkroom(BARRACKS); 715. 	else 716. #endif 717. 	if(depth(&u.uz) > 18 && !rn2(6)) mkroom(SWAMP); 718.  719.  #ifdef REINCARNATION 720. skip0: 721. #endif 722. 	/* Place multi-dungeon branch. */ 723.  	place_branch(Is_branchlev(&u.uz), 0, 0); 724.  725.  	/* for each room: put things inside */ 726. 	for(croom = rooms; croom->hx > 0; croom++) { 727. 		if(croom->rtype != OROOM) continue; 728.  729.  		/* put a sleeping monster inside */ 730. 		/* Note: monster may be on the stairs. This cannot be 731. avoided: maybe the player fell through a trap door 732. 		   while a monster was on the stairs. Conclusion: 733. 		   we have to check for monsters on the stairs anyway. */ 734.   735.  		if(u.uhave.amulet || !rn2(3)) { 736. 		    x = somex(croom); y = somey(croom); 737. 		    tmonst = makemon((struct permonst *) 0, x,y); 738. 		    if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] &&  739.  			!is_pool(x,y)) 740. 			(void) maketrap (x,y,WEB); 741. 		}  742.  		/* put traps and mimics inside */ 743. 		goldseen = FALSE; 744. 		x = 8 - (level_difficulty/6); 745. 		if (x <= 1) x = 2; 746. 		while (!rn2(x)) 747. 		    mktrap(0,0,croom,(coord*)0); 748. 		if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom)); 749. #ifdef REINCARNATION 750. 		if(Is_rogue_level(&u.uz)) goto skip_nonrogue; 751. #endif 752. 		if(!rn2(10)) mkfount(0,croom); 753. #ifdef SINKS 754. 		if(!rn2(60)) mksink(croom); 755. #endif 756. 		if(!rn2(60)) mkaltar(croom); 757. 		/* put statues inside */ 758. 		if(!rn2(20)) 759. 		    (void) mkcorpstat(STATUE, (struct permonst *)0,  760.  				      somex(croom), somey(croom), TRUE); 761.  762.  		/* put box/chest inside; 763. 		 *  40% chance for at least 1 box, regardless of number 764. 		 *  of rooms; about 5 - 7.5% for 2 boxes, least likely 765. 		 *  when few rooms; chance for 3 or more is neglible. 766. 		 */  767.  		if(!rn2(nroom * 5 / 2)) 768. 		    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,  769.  				     somex(croom), somey(croom), TRUE); 770.  771.  		/* maybe make some graffiti */ 772. 		if(!rn2(27 + 3 * depth(&u.uz))) { 773. 		    const char *mesg = random_engraving; 774. 		    if (mesg) { 775. 			do { 776. 			    x = somex(croom);  y = somey(croom); 777. 			} while(levl[x][y].typ != ROOM && !rn2(40)); 778. 			if (!(IS_POOL(levl[x][y].typ) || 779. 			      IS_FURNITURE(levl[x][y].typ))) 780. 			    make_engr_at(x, y, mesg, 0L, MARK); 781. 		    }  782.  		}  783.   784.  #ifdef REINCARNATION 785. 	skip_nonrogue: 786. #endif 787. 		if(!rn2(3)) { 788. 		    (void) mkobj_at(0, somex(croom), somey(croom), TRUE); 789. 		    tryct = 0; 790. 		    while(!rn2(5)) { 791. 			if(++tryct > 100) { 792. 			    impossible("tryct overflow4"); 793. 			    break; 794. 			}  795.  			(void) mkobj_at(0, somex(croom), somey(croom), TRUE); 796. 		    }  797.  		}  798.  	}  799.  }  800.   801.  void 802. mklev 803. {  804.  	struct mkroom *croom; 805.  806.  	if(getbones) return; 807. 	in_mklev = TRUE; 808. 	makelevel; 809. 	bound_digging; 810. 	in_mklev = FALSE; 811. 	if(!level.flags.is_maze_lev) { 812. 	    for (croom = &rooms[0]; croom != &rooms[nroom]; croom++) 813. #ifdef SPECIALIZATION 814. 		topologize(croom, FALSE); 815. #else 816. 		topologize(croom); 817. #endif 818. 	}  819.  }  820.   821.  void 822. #ifdef SPECIALIZATION 823. topologize(croom, do_ordinary) 824. register struct mkroom *croom; 825. boolean do_ordinary; 826. #else 827. topologize(croom) 828. register struct mkroom *croom; 829. #endif 830. {  831.  	register int x, y, roomno = (croom - rooms) + ROOMOFFSET; 832. 	register int lowx = croom->lx, lowy = croom->ly; 833. 	register int hix = croom->hx, hiy = croom->hy; 834. #ifdef SPECIALIZATION 835. 	register schar rtype = croom->rtype; 836. #endif 837. 	register int subindex, nsubrooms = croom->nsubrooms; 838.  839.  	/* skip the room if already done; i.e. a shop handled out of order */ 840. 	/* also skip if this is non-rectangular (it _must_ be done already) */ 841. 	if (levl[lowx][lowy].roomno == roomno || croom->irregular) 842. 	    return; 843. #ifdef SPECIALIZATION 844. # ifdef REINCARNATION 845. 	if (Is_rogue_level(&u.uz)) 846. 	    do_ordinary = TRUE;		/* vision routine helper */ 847. # endif 848. 	if ((rtype != OROOM) || do_ordinary) 849. #endif 850. 	{  851.  	    /* do innards first */ 852. 	    for(x = lowx; x <= hix; x++) 853. 		for(y = lowy; y <= hiy; y++) 854. #ifdef SPECIALIZATION 855. 		    if (rtype == OROOM) 856. 			levl[x][y].roomno = NO_ROOM; 857. 		    else 858. #endif 859. 			levl[x][y].roomno = roomno; 860. 	    /* top and bottom edges */ 861. 	    for(x = lowx-1; x <= hix+1; x++) 862. 		for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 863. 		    levl[x][y].edge = 1; 864. 		    if (levl[x][y].roomno) 865. 			levl[x][y].roomno = SHARED; 866. 		    else 867. 			levl[x][y].roomno = roomno; 868. 		}  869.  	    /* sides */ 870. 	    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 871. 		for(y = lowy; y <= hiy; y++) { 872. 		    levl[x][y].edge = 1; 873. 		    if (levl[x][y].roomno) 874. 			levl[x][y].roomno = SHARED; 875. 		    else 876. 			levl[x][y].roomno = roomno; 877. 		}  878.  	}  879.  	/* subrooms */ 880. 	for (subindex = 0; subindex < nsubrooms; subindex++) 881. #ifdef SPECIALIZATION 882. 		topologize(croom->sbrooms[subindex], (rtype != OROOM)); 883. #else 884. 		topologize(croom->sbrooms[subindex]); 885. #endif 886. }  887.   888.  /* Find an unused room for a branch location. */ 889.  static struct mkroom * 890. find_branch_room(mp) 891.     coord *mp; 892. {  893.      struct mkroom *croom = 0; 894.  895.      if (nroom == 0) { 896. 	mazexy(mp);		/* already verifies location */ 897.     } else { 898. 	/* not perfect - there may be only one stairway */ 899. 	if(nroom > 2) { 900. 	    int tryct = 0; 901.  902.  	    do  903. croom = &rooms[rn2(nroom)]; 904. 	    while((croom == dnstairs_room || croom == upstairs_room || 905. 		  croom->rtype != OROOM) && (++tryct < 100)); 906. 	} else 907. 	    croom = &rooms[rn2(nroom)]; 908.  909.  	do { 910. 	    if (!somexy(croom, mp)) 911. 		impossible("Can't place branch!"); 912. 	} while(occupied(mp->x, mp->y) ||  913.  	    (levl[mp->x][mp->y].typ != CORR && levl[mp->x][mp->y].typ != ROOM)); 914.     }  915.      return croom; 916. }  917.   918.  /* Find the room for (x,y). Return NULL of not in a room. */ 919.  static struct mkroom * 920. pos_to_room(x, y)  921. xchar x, y; 922. { 923.      int i;  924. struct mkroom *curr; 925.  926.      for (curr = rooms, i = 0; i < nroom; curr++, i++) 927. 	if (inside_room(curr, x, y)) return curr;; 928.     return (struct mkroom *) 0; 929. }  930.   931.   932.  /* If given a branch, randomly place a special stair or portal. */ 933.  void 934. place_branch(br, x, y)  935. branch *br;	/* branch to place */ 936. xchar x, y;	/* location */ 937. {  938.  	coord	      m;  939. d_level	     *dest; 940. 	boolean	      make_stairs; 941. 	struct mkroom *br_room; 942.  943.  	/*  944.  	 * Return immediately if there is no branch to make or we have 945. 	 * already made one. This routine can be called twice when 946. 	 * a special level is loaded that specifies an SSTAIR location 947. 	 * as a favored spot for a branch. 948. 	 */  949.  	if (!br || made_branch) return; 950.  951.  	if (!x) {	/* find random coordinates for branch */ 952. 	    br_room = find_branch_room(&m); 953. 	    x = m.x;  954. y = m.y; 955. } else { 956. 	    br_room = pos_to_room(x, y); 957. 	}  958.   959.  	if (on_level(&br->end1, &u.uz)) { 960. 	    /* we're on end1 */ 961. 	    make_stairs = br->type != BR_NO_END1; 962. 	    dest = &br->end2; 963. 	} else { 964. 	    /* we're on end2 */ 965. 	    make_stairs = br->type != BR_NO_END2; 966. 	    dest = &br->end1; 967. 	}  968.   969.  	if (br->type == BR_PORTAL) { 970. 	    mkportal(x, y, dest->dnum, dest->dlevel); 971. 	} else if (make_stairs) { 972. 	    sstairs.sx = x;  973. sstairs.sy = y; 974. sstairs.up = (char) on_level(&br->end1, &u.uz) ? 975. 					    br->end1_up : !br->end1_up; 976. 	    assign_level(&sstairs.tolev, dest); 977. 	    sstairs_room = br_room; 978.  979.  	    levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN; 980. 	    levl[x][y].typ = STAIRS; 981. 	}  982.  	/*  983.  	 * Set made_branch to TRUE even if we didn't make a stairwell (i.e.  984.  	 * make_stairs is false) since there is currently only one branch 985. 	 * per level, if we failed once, we're going to fail again on the 986. 	 * next call. 987. 	 */  988.  	made_branch = TRUE; 989. }  990.   991.  static boolean 992. bydoor(x, y)  993. register xchar x, y; 994. { 995.  	register boolean tmp1, tmp2; 996.  997.  	/* break up large expression to help some compilers */ 998. 	tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||  999.  		IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR); 1000. 	tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR || 1001. 		IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR); 1002. 	return(tmp1 || tmp2); 1003. } 1004.  1005. /* see whether it is allowable to create a door at [x,y] */ 1006. int 1007. okdoor(x,y) 1008. register xchar x, y; 1009. { 1010. 	register boolean near_door = bydoor(x, y); 1011. 1012. 	return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&  1013. 			doorindex < DOORMAX && !near_door); 1014. } 1015.  1016. void 1017. dodoor(x,y,aroom) 1018. register int x, y; 1019. register struct mkroom *aroom; 1020. { 1021. 	if(doorindex >= DOORMAX) { 1022. 		impossible("DOORMAX exceeded?"); 1023. 		return; 1024. 	} 1025.  1026. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); 1027. } 1028.  1029. boolean 1030. occupied(x, y) 1031. register xchar x, y; 1032. { 1033. 	return(t_at(x, y) || levl[x][y].typ == STAIRS  1034. 		|| IS_FOUNTAIN(levl[x][y].typ)  1035. 		|| IS_THRONE(levl[x][y].typ)  1036. #ifdef SINKS  1037. 		|| IS_SINK(levl[x][y].typ)  1038. #endif  1039. 		|| levl[x][y].typ == ALTAR  1040. 		|| is_lava(x,y)  1041. 		|| is_pool(x,y)  1042. 		|| invocation_pos(x,y)  1043. 		); 1044. } 1045.  1046. /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */ 1047. /* if tm != NULL, make trap at that location */ 1048. void 1049. mktrap(num, mazeflag, croom, tm) 1050. register int num, mazeflag; 1051. register struct mkroom *croom; 1052. coord *tm; 1053. { 1054. 	register int kind; 1055. 	coord m; 1056. 1057. 	/* no traps in pools */ 1058. 	if (tm && is_pool(tm->x,tm->y)) return; 1059. 1060. 	if (num > 0 && num < TRAPNUM) { 1061. 	   kind = num; 1062. #ifdef REINCARNATION 1063. 	} else if (Is_rogue_level(&u.uz)) { 1064. 	   switch (rn2(7)) { 1065. 		default: kind = BEAR_TRAP; break; /* 0 */ 1066. 		case 1: kind = ARROW_TRAP; break; 1067. 		case 2: kind = DART_TRAP; break; 1068. 		case 3: kind = TRAPDOOR; break; 1069. 		case 4: kind = PIT; break; 1070. 		case 5: kind = SLP_GAS_TRAP; break; 1071. 		case 6: kind = RUST_TRAP; break; 1072. 	   }  1073. #endif 1074. 	} else if (Inhell && !rn2(5)) { 1075. 	   /* bias the frequency of fire traps in Gehennom */ 1076. 	   kind = FIRE_TRAP; 1077. 	} else { 1078. 	   unsigned lvl = level_difficulty; 1079. 1080. 	    do { 1081. 		kind = rnd(TRAPNUM-1); 1082. 		/* reject "too hard" traps */ 1083. 		switch (kind) { 1084. 		   case LEVEL_TELEP: 1085. 		   case LANDMINE: 1086. 			if (lvl < 5) kind = NO_TRAP; break; 1087. 		   case SPIKED_PIT: 1088. #ifdef POLYSELF 1089. 		   case POLY_TRAP: 1090. #endif 1091. 			if (lvl < 6) kind = NO_TRAP; break; 1092. 		   case WEB: 1093. 		   case STATUE_TRAP: 1094. 			if (lvl < 7) kind = NO_TRAP; break; 1095. 		   case FIRE_TRAP: 1096. 			if (!Inhell) kind = NO_TRAP; break; 1097. 		} 1098. 	    } while (kind == NO_TRAP || kind == MAGIC_PORTAL); 1099. 	} 1100.  1101. 	if (kind == TRAPDOOR && !Can_fall_thru(&u.uz)) kind = ROCKTRAP; 1102. 1103. 	if (tm) 1104. 	   m = *tm; 1105. 	else { 1106. 	   register int tryct = 0; 1107. 1108. 	    do { 1109. 		if (++tryct > 200) 1110. 		   return; 1111. 		if (mazeflag) 1112. 		   mazexy(&m); 1113. 		else if (!somexy(croom,&m)) 1114. 		   return; 1115. 	   } while (occupied(m.x, m.y) || is_pool(m.x,m.y) ||  1116. 				     (sobj_at(BOULDER, m.x, m.y) && 1117. 				     (kind == PIT || kind == SPIKED_PIT ||  1118. 				       kind == TRAPDOOR))); 1119. 	} 1120.  1121. 	(void) maketrap(m.x, m.y, kind); 1122. 	if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], m.x, m.y); 1123. } 1124.  1125. void 1126. mkstairs(x, y, up, croom) 1127. xchar x, y; 1128. char up; 1129. struct mkroom *croom; 1130. { 1131. 	if (! (x || y)) { 1132. 	   impossible("mkstairs:  bogus stair attempt at (%d,%d)", x, y); 1133. 	   return; 1134. 	} 1135.  1136. 	/*  1137. 	 * We can't make a regular stair off an end of the dungeon. This 1138. 	 * attempt can happen when a special level is placed at an end and 1139. 	 * has an up or down stair specified in its description file. 1140. 	 */ 1141. 	if ((dunlev(&u.uz) == 1 && up) ||  1142. 			(dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up)) 1143. 	   return; 1144. 1145. 	if(up) { 1146. 		xupstair = x; 1147. yupstair = y; 1148. upstairs_room = croom; 1149. 	} else { 1150. 		xdnstair = x; 1151. ydnstair = y; 1152. dnstairs_room = croom; 1153. 	} 1154.  1155. 	levl[x][y].typ = STAIRS; 1156. 	levl[x][y].ladder = up ? LA_UP : LA_DOWN; 1157. } 1158.  1159. static 1160. void 1161. mkfount(mazeflag,croom) 1162. register int mazeflag; 1163. register struct mkroom *croom; 1164. { 1165. 	coord m;  1166. register int tryct = 0; 1167. 1168. 	do { 1169. 	   if(++tryct > 200) return; 1170. 	   if(mazeflag) 1171. 		mazexy(&m); 1172. 	   else 1173. 		if (!somexy(croom, &m)) 1174. 		   return; 1175. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y)); 1176. 1177. 	/* Put a fountain at m.x, m.y */ 1178. 	levl[m.x][m.y].typ = FOUNTAIN; 1179. 	/* Is it a "blessed" fountain? (affects drinking from fountain) */ 1180. 	if(!rn2(7)) levl[m.x][m.y].blessedftn = 1; 1181. 1182. 	level.flags.nfountains++; 1183. } 1184.  1185. #ifdef SINKS 1186. static void 1187. mksink(croom) 1188. register struct mkroom *croom; 1189. { 1190. 	coord m;  1191. register int tryct = 0; 1192. 1193. 	do { 1194. 	   if(++tryct > 200) return; 1195. 	   if (!somexy(croom, &m)) 1196. 		return; 1197. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y)); 1198. 1199. 	/* Put a sink at m.x, m.y */ 1200. 	levl[m.x][m.y].typ = SINK; 1201. 1202. 	level.flags.nsinks++; 1203. } 1204. #endif /* SINKS /**/ 1205. 1206.  1207. static void 1208. mkaltar(croom) 1209. register struct mkroom *croom; 1210. { 1211. 	coord m;  1212. register int tryct = 0; 1213. 	aligntyp al; 1214. 1215. 	if(croom->rtype != OROOM) return; 1216. 1217. 	do { 1218. 	   if(++tryct > 200) return; 1219. 	   if (!somexy(croom, &m)) 1220. 		return; 1221. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y)); 1222. 1223. 	/* Put an altar at m.x, m.y */ 1224. 	levl[m.x][m.y].typ = ALTAR; 1225. 1226. 	/* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */ 1227. 	al = rn2((int)A_LAWFUL+2) - 1; 1228. 	levl[m.x][m.y].altarmask = Align2amask( al ); 1229. } 1230.  1231. /*  1232.  * Major level transmutation: add a set of stairs (to the Sanctum) after 1233. * an earthquake that leaves behind a a new topology, centered at inv_pos. 1234. * Assumes there are no rooms within the invocation area and that inv_pos 1235. * is not too close to the edge of the map. Also assume the hero can see. 1236. */  1237. void 1238. mkinvokearea 1239. { 1240.     int dist; 1241.    xchar xmin = inv_pos.x, xmax = inv_pos.x;  1242. xchar ymin = inv_pos.y, ymax = inv_pos.y; 1243. register xchar i; 1244. 1245.    pline("The floor shakes violently under you!"); 1246.    pline("The walls around you begin to move and fall down!"); 1247.    display_nhwindow(WIN_MESSAGE, TRUE); 1248. 1249.     for(dist = 1; dist < 7; dist++) { 1250. 	xmin--; xmax++; 1251. 1252. 	/* top and bottom */ 1253. 	if(dist != 3) { /* the area is wider that it is high */ 1254. 	   ymin--; ymax++; 1255. 	   for(i = xmin+1; i < xmax; i++) { 1256. 		mkinvpos(i, ymin, dist); 1257. 		mkinvpos(i, ymax, dist); 1258. 	   }  1259. 	}  1260.  1261. 	/* left and right */ 1262. 	for(i = ymin; i <= ymax; i++) { 1263. 	   mkinvpos(xmin, i, dist); 1264. 	   mkinvpos(xmax, i, dist); 1265. 	} 1266.  1267. 	flush_screen(1);	/* make sure the new glyphs shows up */ 1268. 	delay_output; 1269.    }  1270.  1271.     You("are standing at the top of a stairwell leading down!"); 1272.    mkstairs(u.ux, u.uy, 0, (struct mkroom *)0); /* down */ 1273.    newsym(u.ux, u.uy); 1274.    vision_full_recalc = 1;	/* everything changed */ 1275. } 1276.  1277. /* Change level topology. Messes with vision tables and ignores things like 1278. * boulders in the name of a nice effect. Vision will get fixed up again 1279. * immediately after the effect is complete. 1280. */  1281. static void 1282. mkinvpos(x,y,dist) 1283. xchar x,y; 1284. int dist; 1285. { 1286.     struct trap *ttmp; 1287.    register struct rm *lev = &levl[x][y]; 1288. 1289.     unblock_point(x,y);	/* make sure vision knows this location is open */ 1290. 1291.     /* fake out saved state */ 1292.    lev->seen = FALSE; 1293.    lev->doormask = 0; 1294.    if(dist < 6) lev->lit = TRUE; 1295.    lev->waslit = TRUE; 1296.    lev->horizontal = FALSE; 1297.    viz_array[y][x] = (dist < 6 ) ? 1298. 	(IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */ 1299. 	COULD_SEE; 1300. 1301.     switch(dist) { 1302.    case 1: /* fire traps */ 1303. 	lev->typ = ROOM; 1304. 	if (is_pool(x,y)) break; 1305. 	ttmp = maketrap(x, y, FIRE_TRAP); 1306. 	ttmp->tseen = TRUE; 1307. 	break; 1308.    case 2: /* lit room locations */ 1309.    case 3: 1310.    case 6: 1311. 	if ((ttmp = t_at(x,y)) != 0) deltrap(ttmp); 1312. 	lev->typ = ROOM; 1313. 	break; 1314.    case 4: /* pools (aka a wide moat) */ 1315.    case 5: 1316. 	if ((ttmp = t_at(x,y)) != 0) deltrap(ttmp); 1317. 	lev->typ = MOAT; 1318. 	break; 1319.    default: 1320. 	impossible("mkinvpos called with dist %d", dist); 1321. 	break; 1322.    }  1323.  1324.     /* display new value of position; could have a monster/object on it */ 1325.    newsym(x,y); 1326. } 1327.  1328. #ifdef MULDGN 1329. /* 1330.  * The portal to Ludios is special. The entrance can only occur within a 1331. * vault in the main dungeon at a depth greater than 10. The Ludios branch 1332. * structure reflects this by having a bogus "source" dungeon:  the value 1333. * of n_dgns (thus, Is_branchlev will never find it). 1334. *  1335.  * Ludios will remain isolated until the branch is corrected by this function. 1336. */  1337. static void 1338. mk_knox_portal(x, y) 1339. xchar x, y; 1340. { 1341. 	extern int n_dgns;		/* from dungeon.c */ 1342. 	d_level *source; 1343. 	branch *br; 1344. 	xchar u_depth; 1345. 1346. 	br = dungeon_branch("Fort Ludios"); 1347. 	if (on_level(&knox_level, &br->end1)) { 1348. 	   source = &br->end2; 1349. 	} else { 1350. 	   /* disallow Knox branch on a level with one branch already */ 1351. 	   if(Is_branchlev(&u.uz)) 1352. 		return; 1353. 	   source = &br->end1; 1354. 	} 1355.  1356. 	/* Already set or 2/3 chance of deferring until a later level. */ 1357. 	if (source->dnum < n_dgns || (rn2(3) 1358. #ifdef WIZARD 1359. 				     && !wizard 1360. #endif 1361. 				     )) return; 1362. 1363. 	if (! (u.uz.dnum == oracle_level.dnum	    /* in main dungeon */ 1364. 		&& !at_dgn_entrance("The Quest")   /* but not Quest's entry */ 1365. 		&& (u_depth = depth(&u.uz)) > 10   /* beneath 10 */ 1366. 		&& u_depth < depth(&medusa_level))) /* and above Medusa */ 1367. 	   return; 1368. 1369. 	/* Adjust source to be current level and re-insert branch. */ 1370. 	*source = u.uz; 1371. 	insert_branch(br, TRUE); 1372. 1373. # ifdef DEBUG 1374. 	pline("Made knox portal."); 1375. # endif 1376. 	place_branch(br, x, y); 1377. } 1378. #endif 1379. 1380. /*mklev.c*/