Source:NetHack 1.3d/mklev.c

Below is the full text to mklev.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/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	1.3	87/07/14 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* mklev.c - version 1.0.3 */ 4.    5.    #include "hack.h"  6. 7.   extern char *getlogin, *getenv; 8.   extern struct monst *makemon; 9.   extern struct obj *mkobj_at; 10.  extern struct trap *maketrap; 11.   12.   #define somex ((rand%(croom->hx-croom->lx+1))+croom->lx) 13.  #define somey ((rand%(croom->hy-croom->ly+1))+croom->ly) 14.   15.   #include "mkroom.h"  16. #define	XLIM	4	/* define minimum required space around a room */ 17.  #define	YLIM	3 18.  boolean secret;		/* TRUE while making a vault: increase [XY]LIM */ 19.  struct mkroom rooms[MAXNROFROOMS+1]; 20.  int smeq[MAXNROFROOMS+1]; 21.  coord doors[DOORMAX]; 22.  int doorindex; 23.  struct rm zerorm; 24.  int comp; 25.  schar nxcor; 26.  boolean goldseen; 27.  int nroom; 28.  xchar xdnstair,xupstair,ydnstair,yupstair; 29.   30.   /* Definitions used by makerooms and addrs */ 31.  #define	MAXRS	50	/* max lth of temp rectangle table - arbitrary */ 32.  struct rectangle { 33.  	xchar rlx,rly,rhx,rhy; 34.  } rs[MAXRS+1]; 35.  int rscnt,rsmax;	/* 0..rscnt-1: currently under consideration */ 36.  			/* rscnt..rsmax: discarded */ 37.   38.   makelevel 39.  {  40.   	register struct mkroom *croom, *troom; 41.  	register unsigned tryct; 42.  #ifndef REGBUG 43.  	register 44.  #endif 45.  		 int x,y; 46.   47.   	nroom = 0; 48.  	doorindex = 0; 49.  	rooms[0].hx = -1;	/* in case we are in a maze */ 50.   51.   	for(x=0; x= rn1(3, 26)) {	/* there might be several mazes */ 57.  		makemaz; 58.  		return; 59.  	}  60.    61.   	/* construct the rooms */ 62.  	nroom = 0; 63.  	secret = FALSE; 64.  	(void) makerooms; 65.   66.   	/* construct stairs (up and down in different rooms if possible) */ 67.  	croom = &rooms[rn2(nroom)]; 68.  	xdnstair = somex; 69.  	ydnstair = somey; 70.  	levl[xdnstair][ydnstair].scrsym ='>'; 71.  	levl[xdnstair][ydnstair].typ = STAIRS; 72.  	if(nroom > 1) { 73.  		troom = croom; 74.  		croom = &rooms[rn2(nroom-1)]; 75.  		if(croom >= troom) croom++; 76.  	}  77.   	xupstair = somex;	/* %% might be in the same place */ 78.  	yupstair = somey; 79.  	levl[xupstair][yupstair].scrsym ='<'; 80.  	levl[xupstair][yupstair].typ = STAIRS; 81.   82.   	/* for each room: put things inside */ 83.  	for(croom = rooms; croom->hx > 0; croom++) { 84.   85.   		/* put a sleeping monster inside */ 86.  		/* Note: monster may be on the stairs. This cannot be 87. avoided: maybe the player fell through a trapdoor 88.  		   while a monster was on the stairs. Conclusion: 89.  		   we have to check for monsters on the stairs anyway. */ 90.   		if(!rn2(3)) (void) 91.  			makemon((struct permonst *) 0, somex, somey); 92.   93.   		/* put traps and mimics inside */ 94.  		goldseen = FALSE; 95.  		while(!rn2(8-(dlevel/6))) mktrap(0,0,croom); 96.  		if(!goldseen && !rn2(3)) mkgold(0L,somex,somey); 97.  #ifdef FOUNTAINS 98.  		if(!rn2(10)) mkfount(0,croom); 99.  #endif 100. 		if(!rn2(3)) { 101. 			(void) mkobj_at(0, somex, somey); 102. 			tryct = 0; 103. 			while(!rn2(5)) { 104. 				if(++tryct > 100){ 105. 					printf("tryct overflow4\n"); 106. 					break; 107. 				}  108.  				(void) mkobj_at(0, somex, somey); 109. 			}  110.  		}  111.  	}  112.   113.  	qsort((char *) rooms, nroom, sizeof(struct mkroom), comp); 114. 	makecorridors; 115. 	make_niches; 116.  117.  	/* make a secret treasure vault, not connected to the rest */ 118. 	if(nroom <= (2*MAXNROFROOMS/3)) if(rn2(3)) { 119. 		troom = &rooms[nroom]; 120. 		secret = TRUE; 121. 		if(makerooms) { 122. 			troom->rtype = VAULT;		/* treasure vault */ 123. 			for(x = troom->lx; x <= troom->hx; x++) 124. 			for(y = troom->ly; y <= troom->hy; y++) 125. 				mkgold((long)(rnd(dlevel*100) + 50), x, y); 126. 			if(!rn2(3)) 127. 				makevtele; 128. 		}  129.  	}  130.   131.  #ifdef WIZARD 132. 	if(wizard && getenv("SHOPTYPE")) mkshop; else 133. #endif 134. 	if(dlevel > 1 && dlevel < 20 && rn2(dlevel) < 3) mkshop; 135. 	else 136. #ifdef NEWCLASS 137. 	if(dlevel > 4 && !rn2(6)) mkzoo(COURT); 138. #endif 139. 	if(dlevel > 6 && !rn2(7)) mkzoo(ZOO); 140. 	else 141. 	if(dlevel > 9 && !rn2(5)) mkzoo(BEEHIVE); 142. 	else 143. 	if(dlevel > 11 && !rn2(6)) mkzoo(MORGUE); 144. 	else 145. 	if(dlevel > 18 && !rn2(6)) mkswamp; 146. }  147.   148.  makerooms { 149. register struct rectangle *rsp; 150. register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy; 151. int tryct = 0, xlim, ylim; 152.  153.  	/* init */ 154. 	xlim = XLIM + secret; 155. 	ylim = YLIM + secret; 156. 	if(nroom == 0) { 157. 		rsp = rs; 158. 		rsp->rlx = rsp->rly = 0; 159. 		rsp->rhx = COLNO-1; 160. 		rsp->rhy = ROWNO-1; 161. 		rsmax = 1; 162. 	}  163.  	rscnt = rsmax; 164.  165.  	/* make rooms until satisfied */ 166. 	while(rscnt > 0 && nroom < MAXNROFROOMS-1) { 167. 		if(!secret && nroom > (MAXNROFROOMS/3) &&  168.  		   !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom))) 169. 			return(0); 170.  171.  		/* pick a rectangle */ 172. 		rsp = &rs[rn2(rscnt)]; 173. 		hx = rsp->rhx; 174. 		hy = rsp->rhy; 175. 		lx = rsp->rlx; 176. 		ly = rsp->rly; 177.  178.  		/* find size of room */ 179. 		if(secret) 180. 			dx = dy = 1; 181. 		else { 182. 			dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8); 183. 			dy = 2 + rn2(4); 184. 			if(dx*dy > 50) 185. 				dy = 50/dx; 186. 		}  187.   188.  		/* look whether our room will fit */ 189. 		if(hx-lx < dx + dx/2 + 2*xlim || hy-ly < dy + dy/3 + 2*ylim) { 190. 					/* no, too small */ 191. 					/* maybe we throw this area out */ 192. 			if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) { 193. 				rscnt--; 194. 				rs[rsmax] = *rsp; 195. 				*rsp = rs[rscnt]; 196. 				rs[rscnt] = rs[rsmax]; 197. 				tryct = 0; 198. 			} else 199. 				tryct++; 200. 			continue; 201. 		}  202.   203.  		lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1); 204. 		lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1); 205. 		hix = lowx + dx; 206. 		hiy = lowy + dy; 207.  208.  		if(maker(lowx, dx, lowy, dy)) { 209. 			if(secret) return(1); 210. 			addrs(lowx-1, lowy-1, hix+1, hiy+1); 211. 			tryct = 0; 212. 		} else 213. 			if(tryct++ > 100) 214. 				break; 215. 	}  216.  	return(0);	/* failed to make vault - very strange */ 217. }  218.   219.  addrs(lowx,lowy,hix,hiy) 220. register int lowx,lowy,hix,hiy; 221. {  222.  	register struct rectangle *rsp; 223. 	register int lx,ly,hx,hy,xlim,ylim; 224. 	boolean discarded; 225.  226.  	xlim = XLIM + secret; 227. 	ylim = YLIM + secret; 228.  229.  	/* walk down since rscnt and rsmax change */ 230. 	for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) { 231. 		  232.  		if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||  233.  		   (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy) 234. 			continue; 235. 		if((discarded = (rsp >= &rs[rscnt]))) { 236. 			*rsp = rs[--rsmax]; 237. 		} else { 238. 			rsmax--; 239. 			rscnt--; 240. 			*rsp = rs[rscnt]; 241. 			if(rscnt != rsmax) 242. 				rs[rscnt] = rs[rsmax]; 243. 		}  244.  		if(lowy - ly > 2*ylim + 4) 245. 			addrsx(lx,ly,hx,lowy-2,discarded); 246. 		if(lowx - lx > 2*xlim + 4) 247. 			addrsx(lx,ly,lowx-2,hy,discarded); 248. 		if(hy - hiy > 2*ylim + 4) 249. 			addrsx(lx,hiy+2,hx,hy,discarded); 250. 		if(hx - hix > 2*xlim + 4) 251. 			addrsx(hix+2,ly,hx,hy,discarded); 252. 	}  253.  }  254.   255.  addrsx(lx,ly,hx,hy,discarded) 256. register int lx,ly,hx,hy; 257. boolean discarded;		/* piece of a discarded area */ 258. {  259.  	register struct rectangle *rsp; 260.  261.  	/* check inclusions */ 262. 	for(rsp = rs; rsp < &rs[rsmax]; rsp++) { 263. 		if(lx >= rsp->rlx && hx <= rsp->rhx &&  264.  		   ly >= rsp->rly && hy <= rsp->rhy) 265. 			return; 266. 	}  267.   268.  	/* make a new entry */ 269. 	if(rsmax >= MAXRS) { 270. #ifdef WIZARD 271. 		if(wizard) pline("MAXRS may be too small."); 272. #endif 273. 		return; 274. 	}  275.  	rsmax++; 276. 	if(!discarded) { 277. 		*rsp = rs[rscnt]; 278. 		rsp = &rs[rscnt]; 279. 		rscnt++; 280. 	}  281.  	rsp->rlx = lx; 282. 	rsp->rly = ly; 283. 	rsp->rhx = hx; 284. 	rsp->rhy = hy; 285. }  286.   287.  comp(x,y) 288. register struct mkroom *x,*y; 289. {  290.  	if(x->lx < y->lx) return(-1); 291. 	return(x->lx > y->lx); 292. }  293.   294.  coord 295. finddpos(xl,yl,xh,yh) { 296. 	coord ff; 297. 	register x,y; 298.  299.  	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); 300. 	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); 301. 	if(okdoor(x, y)) 302. 		goto gotit; 303.  304.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 305. 		if(okdoor(x, y)) 306. 			goto gotit; 307.  308.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 309. 		if(levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR) 310. 			goto gotit; 311. 	/* cannot find something reasonable -- strange */ 312. 	x = xl; 313. 	y = yh; 314. gotit: 315. 	ff.x = x;  316. ff.y = y; 317. return(ff); 318. }  319.   320.  /* see whether it is allowable to create a door at [x,y] */ 321. okdoor(x,y) 322. register x,y; 323. {  324.  	if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||  325.  	   levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||  326.  	   levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||  327.  	   levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||  328.  	   (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||  329.  	   doorindex >= DOORMAX) 330. 		return(0); 331. 	return(1); 332. }  333.   334.  dodoor(x,y,aroom) 335. register x,y; 336. register struct mkroom *aroom; 337. {  338.  	if(doorindex >= DOORMAX) { 339. 		impossible("DOORMAX exceeded?"); 340. 		return; 341. 	}  342.  	if(!okdoor(x,y) && nxcor) 343. 		return; 344. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); 345. }  346.   347.  dosdoor(x,y,aroom,type) 348. register x,y; 349. register struct mkroom *aroom; 350. register type; 351. {  352.  	register struct mkroom *broom; 353. 	register tmp; 354.  355.  	if(!IS_WALL(levl[x][y].typ))	/* avoid SDOORs with '+' as scrsym */ 356. 		type = DOOR; 357. 	levl[x][y].typ = type; 358. 	if(type == DOOR) 359. #ifdef DGK 360. 		levl[x][y].scrsym = symbol.door; 361. #else 362. 		levl[x][y].scrsym = '+'; 363. #endif /* DGK /**/ 364. 	aroom->doorct++; 365. 	broom = aroom+1; 366. 	if(broom->hx < 0) tmp = doorindex; else 367. 	for(tmp = doorindex; tmp > broom->fdoor; tmp--) 368. 		doors[tmp] = doors[tmp-1]; 369. 	doorindex++; 370. 	doors[tmp].x = x;  371. doors[tmp].y = y; 372. for(broom->hx >= 0; broom++) broom->fdoor++; 373. }  374.   375.  /* Only called from makerooms */ 376. maker(lowx,ddx,lowy,ddy) 377. schar lowx,ddx,lowy,ddy; 378. {  379.  	register struct mkroom *croom; 380. 	register x, y, hix = lowx+ddx, hiy = lowy+ddy; 381. 	register xlim = XLIM + secret, ylim = YLIM + secret; 382.  383.  	if(nroom >= MAXNROFROOMS) return(0); 384. 	if(lowx < XLIM) lowx = XLIM; 385. 	if(lowy < YLIM) lowy = YLIM; 386. 	if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1; 387. 	if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1; 388. chk: 389. 	if(hix <= lowx || hiy <= lowy) return(0); 390.  391.  	/* check area around room (and make room smaller if necessary) */ 392. 	for(x = lowx - xlim; x <= hix + xlim; x++) { 393. 		for(y = lowy - ylim; y <= hiy + ylim; y++) { 394. 			if(levl[x][y].typ) { 395. #ifdef WIZARD 396. 			    if(wizard && !secret) 397. 				pline("Strange area [%d,%d] in maker.",x,y); 398. #endif 399. 				if(!rn2(3)) return(0); 400. 				if(x < lowx) 401. 					lowx = x+xlim+1; 402. 				else 403. 					hix = x-xlim-1; 404. 				if(y < lowy) 405. 					lowy = y+ylim+1; 406. 				else 407. 					hiy = y-ylim-1; 408. 				goto chk; 409. 			}  410.  		}  411.  	}  412.   413.  	croom = &rooms[nroom]; 414.  415.  	/* on low levels the room is lit (usually) */ 416. 	/* secret vaults are always lit */ 417. 	if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) { 418. 		for(x = lowx-1; x <= hix+1; x++) 419. 			for(y = lowy-1; y <= hiy+1; y++) 420. 				levl[x][y].lit = 1; 421. 		croom->rlit = 1; 422. 	} else 423. 		croom->rlit = 0; 424. 	croom->lx = lowx; 425. 	croom->hx = hix; 426. 	croom->ly = lowy; 427. 	croom->hy = hiy; 428. 	croom->rtype = croom->doorct = croom->fdoor = 0; 429.  430.  #ifdef DGK 431. 	for(x = lowx-1; x <= hix+1; x++) 432. 	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 433. 		levl[x][y].scrsym = symbol.hwall; 434. 		levl[x][y].typ = HWALL; 435. 	}  436.  	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 437. 	    for(y = lowy; y <= hiy; y++) { 438. 		levl[x][y].scrsym = symbol.vwall; 439. 		levl[x][y].typ = VWALL; 440. 	}  441.  	for(x = lowx; x <= hix; x++) 442. 	    for(y = lowy; y <= hiy; y++) { 443. 		levl[x][y].scrsym = symbol.room; 444. 		levl[x][y].typ = ROOM; 445. 	}  446.  	levl[lowx-1][lowy-1].scrsym = symbol.tlcorn; 447. 	levl[hix+1][lowy-1].scrsym = symbol.trcorn; 448. 	levl[lowx-1][hiy+1].scrsym = symbol.blcorn; 449. 	levl[hix+1][hiy+1].scrsym = symbol.brcorn; 450. #else 451. 	for(x = lowx-1; x <= hix+1; x++) 452. 	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 453. 		levl[x][y].scrsym = '-'; 454. 		levl[x][y].typ = HWALL; 455. 	}  456.  	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 457. 	    for(y = lowy; y <= hiy; y++) { 458. 		levl[x][y].scrsym = '|'; 459. 		levl[x][y].typ = VWALL; 460. 	}  461.  	for(x = lowx; x <= hix; x++) 462. 	    for(y = lowy; y <= hiy; y++) { 463. 		levl[x][y].scrsym = '.'; 464. 		levl[x][y].typ = ROOM; 465. 	}  466.  #endif /* DGK /**/ 467.  468.  	smeq[nroom] = nroom; 469. 	croom++; 470. 	croom->hx = -1; 471. 	nroom++; 472. 	return(1); 473. }  474.   475.  makecorridors { 476. 	register a,b; 477.  478.  	nxcor = 0; 479. 	for(a = 0; a < nroom-1; a++) 480. 		join(a, a+1); 481. 	for(a = 0; a < nroom-2; a++) 482. 	    if(smeq[a] != smeq[a+2]) 483. 		join(a, a+2); 484. 	for(a = 0; a < nroom; a++) 485. 	    for(b = 0; b < nroom; b++) 486. 		if(smeq[a] != smeq[b]) 487. 		    join(a, b); 488. 	if(nroom > 2) 489. 	    for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) { 490. 		a = rn2(nroom); 491. 		b = rn2(nroom-2); 492. 		if(b >= a) b += 2; 493. 		join(a, b); 494. 	    }  495.  }  496.   497.  join(a,b) 498. register a,b; 499. {  500.  	coord cc,tt; 501. 	register tx, ty, xx, yy; 502. 	register struct rm *crm; 503. 	register struct mkroom *croom, *troom; 504. 	register dx, dy, dix, diy, cct; 505.  506.  	croom = &rooms[a]; 507. 	troom = &rooms[b]; 508.  509.  	/* find positions cc and tt for doors in croom and troom 510. 	   and direction for a corridor between them */ 511.  512.  	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; 513. 	if(troom->lx > croom->hx) { 514. 		dx = 1; 515. 		dy = 0; 516. 		xx = croom->hx+1; 517. 		tx = troom->lx-1; 518. 		cc = finddpos(xx,croom->ly,xx,croom->hy); 519. 		tt = finddpos(tx,troom->ly,tx,troom->hy); 520. 	} else if(troom->hy < croom->ly) { 521. 		dy = -1; 522. 		dx = 0; 523. 		yy = croom->ly-1; 524. 		cc = finddpos(croom->lx,yy,croom->hx,yy); 525. 		ty = troom->hy+1; 526. 		tt = finddpos(troom->lx,ty,troom->hx,ty); 527. 	} else if(troom->hx < croom->lx) { 528. 		dx = -1; 529. 		dy = 0; 530. 		xx = croom->lx-1; 531. 		tx = troom->hx+1; 532. 		cc = finddpos(xx,croom->ly,xx,croom->hy); 533. 		tt = finddpos(tx,troom->ly,tx,troom->hy); 534. 	} else { 535. 		dy = 1; 536. 		dx = 0; 537. 		yy = croom->hy+1; 538. 		ty = troom->ly-1; 539. 		cc = finddpos(croom->lx,yy,croom->hx,yy); 540. 		tt = finddpos(troom->lx,ty,troom->hx,ty); 541. 	}  542.  	xx = cc.x;  543. yy = cc.y; 544. tx = tt.x - dx; 545. 	ty = tt.y - dy; 546. 	if(nxcor && levl[xx+dx][yy+dy].typ) 547. 		return; 548. 	dodoor(xx,yy,croom); 549.  550.  	cct = 0; 551. 	while(xx != tx || yy != ty) { 552. 	    xx += dx; 553. 	    yy += dy; 554.  555.  	    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ 556. 	    if(cct++ > 500 || (nxcor && !rn2(35))) 557. 		return; 558.  559.  	    if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) 560. 		return;		/* impossible */ 561.  562.  	    crm = &levl[xx][yy]; 563. 	    if(!(crm->typ)) { 564. 		if(rn2(100)) { 565. 			crm->typ = CORR; 566. #ifdef DGK 567. 			crm->scrsym = symbol.corr; 568. #else 569. 			crm->scrsym = CORR_SYM; 570. #endif 571. 			if(nxcor && !rn2(50)) 572. 				(void) mkobj_at(ROCK_SYM, xx, yy); 573. 		} else { 574. 			crm->typ = SCORR; 575. 			crm->scrsym = ' '; 576. 		}  577.  	    } else 578. 	    if(crm->typ != CORR && crm->typ != SCORR) { 579. 		/* strange ... */ 580.  		return; 581. 	    }  582.   583.  	    /* find next corridor position */ 584. 	    dix = abs(xx-tx); 585. 	    diy = abs(yy-ty); 586.  587.  	    /* do we have to change direction ? */ 588.  	    if(dy && dix > diy) { 589. 		register ddx = (xx > tx) ? -1 : 1; 590.   591.  		crm = &levl[xx+ddx][yy]; 592. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 593. 		    dx = ddx; 594. 		    dy = 0; 595. 		    continue; 596. 		}  597.  	    } else if(dx && diy > dix) { 598. 		register ddy = (yy > ty) ? -1 : 1; 599.   600.  		crm = &levl[xx][yy+ddy]; 601. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 602. 		    dy = ddy; 603. 		    dx = 0; 604. 		    continue; 605. 		}  606.  	    }  607.   608.  	    /* continue straight on? */ 609.  	    crm = &levl[xx+dx][yy+dy]; 610. 	    if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 611. 		continue; 612.  613.  	    /* no, what must we do now?? */ 614.  	    if(dx) { 615. 		dx = 0; 616. 		dy = (ty < yy) ? -1 : 1; 617.  		crm = &levl[xx+dx][yy+dy]; 618. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 619. 		    continue; 620. 		dy = -dy; 621. 		continue; 622. 	    } else { 623. 		dy = 0; 624. 		dx = (tx < xx) ? -1 : 1; 625.  		crm = &levl[xx+dx][yy+dy]; 626. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 627. 		    continue; 628. 		dx = -dx; 629. 		continue; 630. 	    }  631.  	}  632.   633.  	/* we succeeded in digging the corridor */ 634. 	dodoor(tt.x, tt.y, troom); 635.  636.  	if(smeq[a] < smeq[b]) 637. 		smeq[b] = smeq[a]; 638. 	else 639. 		smeq[a] = smeq[b]; 640. }  641.   642.  make_niches 643. {  644.  	register int ct = rnd(nroom/2 + 1); 645. #ifdef NEWCLASS 646. 	boolean	ltptr = TRUE, 647. 		vamp = TRUE; 648.  649.  	while(ct--) { 650.  651.  		if(dlevel > 15 && rn1(6,0) == 0 && ltptr) { 652.  653.  			ltptr = FALSE; 654. 			makeniche(LEVEL_TELEP); 655. 		} if (rn1(6,0) == 0)	{ 656.  657.  			vamp = FALSE; 658. 			makeniche(TRAPDOOR); 659. 		} else	makeniche(NO_TRAP); 660. 	}  661.  #else 662. 	while(ct--) makeniche(NO_TRAP); 663. #endif 664. }  665.   666.  makevtele 667. {  668.  	makeniche(TELEP_TRAP); 669. }  670.   671.  /* there should be one of these per trap */ 672. char    *engravings[] = {       "", "", "", "", "", 673. 				"ad ae?ar um", "?la? ?as ?er?", 674. 				"", "", ""  675.  #ifdef NEWTRAPS 676. 				,"", ""  677.  #endif 678. #ifdef SPIDERS 679. 				,""  680.  #endif 681. #ifdef NEWCLASS 682. 			, "", "ad ae?ar um" 683. #endif 684. #ifdef SPELLS 685. 				,""  686.  #endif 687. 				};  688.   689.  makeniche(trap_type) 690. int trap_type; 691. {  692.  	register struct mkroom *aroom; 693. 	register struct rm *rm; 694. 	register int vct = 8; 695. 	coord dd; 696. 	register dy,xx,yy; 697. 	register struct trap *ttmp; 698.  699.  	if(doorindex < DOORMAX) 700. 	  while(vct--) { 701. 	    aroom = &rooms[rn2(nroom-1)]; 702. 	    if(aroom->rtype != 0) continue;	/* not an ordinary room */ 703. 	    if(aroom->doorct == 1 && rn2(5)) continue; 704. 	    if(rn2(2)) { 705. 		dy = 1; 706. 		dd = finddpos(aroom->lx,aroom->hy+1,aroom->hx,aroom->hy+1); 707. 	    } else { 708. 		dy = -1; 709. 		dd = finddpos(aroom->lx,aroom->ly-1,aroom->hx,aroom->ly-1); 710. 	    }  711.  	    xx = dd.x;  712. yy = dd.y; 713. if((rm = &levl[xx][yy+dy])->typ) continue; 714. 	    if(trap_type || !rn2(4)) { 715.  716.  		rm->typ = SCORR; 717. 		rm->scrsym = ' '; 718. 		if(trap_type) { 719. 		    ttmp = maketrap(xx, yy+dy, trap_type); 720. 		    ttmp->once = 1; 721. 		    if (strlen(engravings[trap_type]) > 0) 722. 			make_engr_at(xx, yy-dy, engravings[trap_type]); 723. 		}  724.  		dosdoor(xx, yy, aroom, SDOOR); 725. 	    } else { 726. 		rm->typ = CORR; 727. #ifdef DGK 728. 		rm->scrsym = symbol.corr; 729. #else 730. 		rm->scrsym = CORR_SYM; 731. #endif 732. 		if(rn2(7)) 733. 		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); 734. 		else { 735. 		    mksobj_at(SCR_TELEPORTATION, xx, yy+dy); 736. 		    if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy); 737. 		}  738.  	    }  739.  	    return; 740. 	}  741.  }  742.   743.  /* make a trap somewhere (in croom if mazeflag = 0) */ 744. mktrap(num, mazeflag, croom) 745. #ifndef REGBUG 746. register 747. #endif 748. 	 int num, mazeflag; 749. #ifndef REGBUG 750. register 751. #endif 752. 	 struct mkroom *croom; 753. {  754.  #ifndef REGBUG 755. 	register 756. #endif 757. 		 struct trap *ttmp; 758. #ifndef REGBUG 759. 	register 760. #endif 761. 		 int kind,nopierc,nomimic,fakedoor,fakegold, 762. #ifdef NEWCLASS 763. 		     nospikes, nolevltp, 764. #endif 765. 		     tryct = 0; 766. 	xchar mx,my; 767. 	extern char fut_geno[]; 768.  769.  	if(!num || num >= TRAPNUM) { 770. 		nopierc = (dlevel < 4) ? 1 : 0; 771.  #ifdef NEWCLASS 772. 		nolevltp = (dlevel < 5) ? 1 : 0; 773.  		nospikes = (dlevel < 6) ? 1 : 0; 774.  #endif 775. 		nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; 776.  		if(index(fut_geno, 'M')) nomimic = 1; 777.  778.  		do { 779. 		    kind = rnd(TRAPNUM-1); 780. 			if((kind == PIERC && nopierc) ||  781.  			   (kind == MIMIC && nomimic)  782.  #ifdef SPIDERS  783.  			   || (kind == WEB)  784.  #endif  785.  #ifdef NEWCLASS  786.  			   || (kind == SPIKED_PIT && nospikes)  787.  			   || (kind == LEVEL_TELEP && nolevltp)  788.  #endif  789.  			   )  kind = NO_TRAP; 790. 		} while(kind == NO_TRAP); 791. 	} else kind = num; 792.  793.  	if(kind == MIMIC) { 794. 		register struct monst *mtmp; 795.  796.  		fakedoor = (!rn2(3) && !mazeflag); 797. 		fakegold = (!fakedoor && !rn2(2)); 798. 		if(fakegold) goldseen = TRUE; 799. 		do { 800. 			if(++tryct > 200) return; 801. 			if(fakedoor) { 802. 				/* note: fakedoor maybe on actual door */ 803. 				if(rn2(2)){ 804. 				    if(rn2(2))	mx = croom->hx+1; 805. 				    else	mx = croom->lx-1; 806. 				    my = somey; 807. 				} else { 808. 				    if(rn2(2))	my = croom->hy+1; 809. 				    else	my = croom->ly-1; 810. 				    mx = somex; 811. 				}  812.  			} else if(mazeflag) { 813. 				extern coord mazexy; 814. 				coord mm; 815. 				mm = mazexy; 816. 				mx = mm.x;  817. my = mm.y; 818. } else { 819. 				mx = somex; 820. 				my = somey; 821. 			}  822.  		} while(m_at(mx,my) || levl[mx][my].typ == STAIRS); 823. 		if(mtmp = makemon(PM_MIMIC,mx,my)) { 824. 		    mtmp->mimic = 1; 825. 		    mtmp->mappearance = 826. #ifdef DGK 827. 			fakegold ? '$' : fakedoor ? symbol.door : 828. #else 829. 			fakegold ? '$' : fakedoor ? '+' : 830.  #endif 831. 			(mazeflag && rn2(2)) ? AMULET_SYM : 832. #ifdef SPELLS 833. 			"=/)%?![<>+" [ rn2(10) ];  834.  #else  835.  			"=/)%?![<>" [ rn2(9) ]; 836. #endif 837. 		}  838.  		return; 839. 	}  840.   841.  	do { 842. 		if(++tryct > 200) 843. 			return; 844. 		if(mazeflag){ 845. 			extern coord mazexy; 846. 			coord mm; 847. 			mm = mazexy; 848. 			mx = mm.x;  849. my = mm.y; 850. } else { 851. 			mx = somex; 852. 			my = somey; 853. 		}  854.  	} while(t_at(mx, my) || levl[mx][my].typ == STAIRS); 855. 	ttmp = maketrap(mx, my, kind); 856. 	if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC) 857. 		ttmp->tseen = 1; 858. }  859.   860.  #ifdef FOUNTAINS 861. mkfount(mazeflag,croom) 862. register struct mkroom *croom; 863. register mazeflag; 864. {  865.        register xchar mx,my; 866.       register int tryct = 0; 867.  868.        do { 869. 	      if(++tryct > 200) 870. 		      return; 871. 	      if(mazeflag){ 872. 		      extern coord mazexy; 873. 		      coord mm; 874. 		      mm = mazexy; 875. 		      mx = mm.x;  876. my = mm.y; 877. } else { 878. 		      mx = somex; 879. 		      my = somey; 880. 	      }  881.        } while(t_at(mx, my) || levl[mx][my].typ == STAIRS  882.  #ifdef NEWCLASS  883.  	      || IS_THRONE(levl[mx][my].typ)  884.  #endif  885.  	     ); 886.  887.         /* Put a fountain at mx, my */ 888.  889.         levl[mx][my].typ = FOUNTAIN; 890.        levl[mx][my].scrsym = FOUNTAIN_SYM; 891.  892.  }  893.  #endif /* FOUNTAINS /**/ 894.