Source:NetHack 2.3e/mklev.c

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