Source:SLASH'EM 0.0.7E7F2/mklev.c

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

The latest source code for vanilla NetHack is at Source code.

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