Source:NetHack 1.4f/mklev.c

Below is the full text to mklev.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/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.4	87/08/08 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.  extern struct mkroom rooms[MAXNROFROOMS+1]; 20.  int smeq[MAXNROFROOMS+1]; 21.  extern coord doors[DOORMAX]; 22.  int doorindex; 23.  struct rm zerorm; 24.  int comp; 25.  schar nxcor; 26.  boolean goldseen; 27.  int nroom; 28.  extern 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 = DN_SYM; 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 = UP_SYM; 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.  finddpos(cc, xl,yl,xh,yh) 295. coord	*cc; 296. int	xl,yl,xh,yh; 297. {  298.  	register x,y; 299.  300.  	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1)); 301. 	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1)); 302. 	if(okdoor(x, y)) 303. 		goto gotit; 304.  305.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 306. 		if(okdoor(x, y)) 307. 			goto gotit; 308.  309.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++) 310. 		if(levl[x][y].typ == DOOR || levl[x][y].typ == SDOOR) 311. 			goto gotit; 312. 	/* cannot find something reasonable -- strange */ 313. 	x = xl; 314. 	y = yh; 315. gotit: 316. 	cc->x = x;  317. cc->y = y; 318. return(0); 319. }  320.   321.  /* see whether it is allowable to create a door at [x,y] */ 322. okdoor(x,y) 323. register x,y; 324. {  325.  	if(levl[x-1][y].typ == DOOR || levl[x+1][y].typ == DOOR ||  326.  	   levl[x][y+1].typ == DOOR || levl[x][y-1].typ == DOOR ||  327.  	   levl[x-1][y].typ == SDOOR || levl[x+1][y].typ == SDOOR ||  328.  	   levl[x][y-1].typ == SDOOR || levl[x][y+1].typ == SDOOR ||  329.  	   (levl[x][y].typ != HWALL && levl[x][y].typ != VWALL) ||  330.  	   doorindex >= DOORMAX) 331. 		return(0); 332. 	return(1); 333. }  334.   335.  dodoor(x,y,aroom) 336. register x,y; 337. register struct mkroom *aroom; 338. {  339.  	if(doorindex >= DOORMAX) { 340. 		impossible("DOORMAX exceeded?"); 341. 		return; 342. 	}  343.  	if(!okdoor(x,y) && nxcor) 344. 		return; 345. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR); 346. }  347.   348.  dosdoor(x,y,aroom,type) 349. register x,y; 350. register struct mkroom *aroom; 351. register type; 352. {  353.  	register struct mkroom *broom; 354. 	register tmp; 355.  356.  	if(!IS_WALL(levl[x][y].typ))	/* avoid SDOORs with DOOR_SYM as scrsym */ 357. 		type = DOOR; 358. 	levl[x][y].typ = type; 359. 	if(type == DOOR) 360. 		levl[x][y].scrsym = DOOR_SYM; 361. 	aroom->doorct++; 362. 	broom = aroom+1; 363. 	if(broom->hx < 0) tmp = doorindex; else 364. 	for(tmp = doorindex; tmp > broom->fdoor; tmp--) 365. 		doors[tmp] = doors[tmp-1]; 366. 	doorindex++; 367. 	doors[tmp].x = x;  368. doors[tmp].y = y; 369. for(broom->hx >= 0; broom++) broom->fdoor++; 370. }  371.   372.  /* Only called from makerooms */ 373. maker(lowx,ddx,lowy,ddy) 374. schar lowx,ddx,lowy,ddy; 375. {  376.  	register struct mkroom *croom; 377. 	register x, y, hix = lowx+ddx, hiy = lowy+ddy; 378. 	register xlim = XLIM + secret, ylim = YLIM + secret; 379.  380.  	if(nroom >= MAXNROFROOMS) return(0); 381. 	if(lowx < XLIM) lowx = XLIM; 382. 	if(lowy < YLIM) lowy = YLIM; 383. 	if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1; 384. 	if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1; 385. chk: 386. 	if(hix <= lowx || hiy <= lowy) return(0); 387.  388.  	/* check area around room (and make room smaller if necessary) */ 389. 	for(x = lowx - xlim; x <= hix + xlim; x++) { 390. 		for(y = lowy - ylim; y <= hiy + ylim; y++) { 391. 			if(levl[x][y].typ) { 392. #ifdef WIZARD 393. 			    if(wizard && !secret) 394. 				pline("Strange area [%d,%d] in maker.",x,y); 395. #endif 396. 				if(!rn2(3)) return(0); 397. 				if(x < lowx) 398. 					lowx = x+xlim+1; 399. 				else 400. 					hix = x-xlim-1; 401. 				if(y < lowy) 402. 					lowy = y+ylim+1; 403. 				else 404. 					hiy = y-ylim-1; 405. 				goto chk; 406. 			}  407.  		}  408.  	}  409.   410.  	croom = &rooms[nroom]; 411.  412.  	/* on low levels the room is lit (usually) */ 413. 	/* secret vaults are always lit */ 414. 	if((rnd(dlevel) < 10 && rn2(77)) || (ddx == 1 && ddy == 1)) { 415. 		for(x = lowx-1; x <= hix+1; x++) 416. 			for(y = lowy-1; y <= hiy+1; y++) 417. 				levl[x][y].lit = 1; 418. 		croom->rlit = 1; 419. 	} else 420. 		croom->rlit = 0; 421. 	croom->lx = lowx; 422. 	croom->hx = hix; 423. 	croom->ly = lowy; 424. 	croom->hy = hiy; 425. 	croom->rtype = croom->doorct = croom->fdoor = 0; 426.  427.  	for(x = lowx-1; x <= hix+1; x++) 428. 	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) { 429. 		levl[x][y].scrsym = HWALL_SYM; 430. 		levl[x][y].typ = HWALL; 431. 	}  432.  	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2)) 433. 	    for(y = lowy; y <= hiy; y++) { 434. 		levl[x][y].scrsym = VWALL_SYM; 435. 		levl[x][y].typ = VWALL; 436. 	}  437.  	for(x = lowx; x <= hix; x++) 438. 	    for(y = lowy; y <= hiy; y++) { 439. 		levl[x][y].scrsym = ROOM_SYM; 440. 		levl[x][y].typ = ROOM; 441. 	}  442.  	levl[lowx-1][lowy-1].scrsym = TLCORN_SYM; 443. 	levl[hix+1][lowy-1].scrsym = TRCORN_SYM; 444. 	levl[lowx-1][hiy+1].scrsym = BLCORN_SYM; 445. 	levl[hix+1][hiy+1].scrsym = BRCORN_SYM; 446.  447.  	smeq[nroom] = nroom; 448. 	croom++; 449. 	croom->hx = -1; 450. 	nroom++; 451. 	return(1); 452. }  453.   454.  makecorridors { 455. 	register a,b; 456.  457.  	nxcor = 0; 458. 	for(a = 0; a < nroom-1; a++) 459. 		join(a, a+1); 460. 	for(a = 0; a < nroom-2; a++) 461. 	    if(smeq[a] != smeq[a+2]) 462. 		join(a, a+2); 463. 	for(a = 0; a < nroom; a++) 464. 	    for(b = 0; b < nroom; b++) 465. 		if(smeq[a] != smeq[b]) 466. 		    join(a, b); 467. 	if(nroom > 2) 468. 	    for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) { 469. 		a = rn2(nroom); 470. 		b = rn2(nroom-2); 471. 		if(b >= a) b += 2; 472. 		join(a, b); 473. 	    }  474.  }  475.   476.  join(a,b) 477. register a,b; 478. {  479.  	coord cc,tt; 480. 	register tx, ty, xx, yy; 481. 	register struct rm *crm; 482. 	register struct mkroom *croom, *troom; 483. 	register dx, dy, dix, diy, cct; 484.  485.  	croom = &rooms[a]; 486. 	troom = &rooms[b]; 487.  488.  	/* find positions cc and tt for doors in croom and troom 489. 	   and direction for a corridor between them */ 490.  491.  	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; 492. 	if(troom->lx > croom->hx) { 493. 		dx = 1; 494. 		dy = 0; 495. 		xx = croom->hx+1; 496. 		tx = troom->lx-1; 497. 		finddpos(&cc, xx, croom->ly, xx, croom->hy); 498. 		finddpos(&tt, tx, troom->ly, tx, troom->hy); 499. 	} else if(troom->hy < croom->ly) { 500. 		dy = -1; 501. 		dx = 0; 502. 		yy = croom->ly-1; 503. 		finddpos(&cc, croom->lx, yy, croom->hx, yy); 504. 		ty = troom->hy+1; 505. 		finddpos(&tt, troom->lx, ty, troom->hx, ty); 506. 	} else if(troom->hx < croom->lx) { 507. 		dx = -1; 508. 		dy = 0; 509. 		xx = croom->lx-1; 510. 		tx = troom->hx+1; 511. 		finddpos(&cc, xx, croom->ly, xx, croom->hy); 512. 		finddpos(&tt, tx, troom->ly, tx, troom->hy); 513. 	} else { 514. 		dy = 1; 515. 		dx = 0; 516. 		yy = croom->hy+1; 517. 		ty = troom->ly-1; 518. 		finddpos(&cc, croom->lx, yy, croom->hx, yy); 519. 		finddpos(&tt, troom->lx, ty, troom->hx, ty); 520. 	}  521.  	xx = cc.x;  522. yy = cc.y; 523. tx = tt.x - dx; 524. 	ty = tt.y - dy; 525. 	if(nxcor && levl[xx+dx][yy+dy].typ) 526. 		return; 527. 	dodoor(xx,yy,croom); 528.  529.  	cct = 0; 530. 	while(xx != tx || yy != ty) { 531. 	    xx += dx; 532. 	    yy += dy; 533.  534.  	    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ 535. 	    if(cct++ > 500 || (nxcor && !rn2(35))) 536. 		return; 537.  538.  	    if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) 539. 		return;		/* impossible */ 540.  541.  	    crm = &levl[xx][yy]; 542. 	    if(!(crm->typ)) { 543. 		if(rn2(100)) { 544. 			crm->typ = CORR; 545. 			crm->scrsym = CORR_SYM; 546. 			if(nxcor && !rn2(50)) 547. 				(void) mkobj_at(ROCK_SYM, xx, yy); 548. 		} else { 549. 			crm->typ = SCORR; 550. 			crm->scrsym = STONE_SYM; 551. 		}  552.  	    } else 553. 	    if(crm->typ != CORR && crm->typ != SCORR) { 554. 		/* strange ... */ 555.  		return; 556. 	    }  557.   558.  	    /* find next corridor position */ 559. 	    dix = abs(xx-tx); 560. 	    diy = abs(yy-ty); 561.  562.  	    /* do we have to change direction ? */ 563.  	    if(dy && dix > diy) { 564. 		register ddx = (xx > tx) ? -1 : 1; 565.   566.  		crm = &levl[xx+ddx][yy]; 567. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 568. 		    dx = ddx; 569. 		    dy = 0; 570. 		    continue; 571. 		}  572.  	    } else if(dx && diy > dix) { 573. 		register ddy = (yy > ty) ? -1 : 1; 574.   575.  		crm = &levl[xx][yy+ddy]; 576. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { 577. 		    dy = ddy; 578. 		    dx = 0; 579. 		    continue; 580. 		}  581.  	    }  582.   583.  	    /* continue straight on? */ 584.  	    crm = &levl[xx+dx][yy+dy]; 585. 	    if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 586. 		continue; 587.  588.  	    /* no, what must we do now?? */ 589.  	    if(dx) { 590. 		dx = 0; 591. 		dy = (ty < yy) ? -1 : 1; 592.  		crm = &levl[xx+dx][yy+dy]; 593. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 594. 		    continue; 595. 		dy = -dy; 596. 		continue; 597. 	    } else { 598. 		dy = 0; 599. 		dx = (tx < xx) ? -1 : 1; 600.  		crm = &levl[xx+dx][yy+dy]; 601. 		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) 602. 		    continue; 603. 		dx = -dx; 604. 		continue; 605. 	    }  606.  	}  607.   608.  	/* we succeeded in digging the corridor */ 609. 	dodoor(tt.x, tt.y, troom); 610.  611.  	if(smeq[a] < smeq[b]) 612. 		smeq[b] = smeq[a]; 613. 	else 614. 		smeq[a] = smeq[b]; 615. }  616.   617.  make_niches 618. {  619.  	register int ct = rnd(nroom/2 + 1); 620. #ifdef NEWCLASS 621. 	boolean	ltptr = TRUE, 622. 		vamp = TRUE; 623.  624.  	while(ct--) { 625.  626.  		if(dlevel > 15 && rn1(6,0) == 0 && ltptr) { 627.  628.  			ltptr = FALSE; 629. 			makeniche(LEVEL_TELEP); 630. 		} if (rn1(6,0) == 0)	{ 631.  632.  			vamp = FALSE; 633. 			makeniche(TRAPDOOR); 634. 		} else	makeniche(NO_TRAP); 635. 	}  636.  #else 637. 	while(ct--) makeniche(NO_TRAP); 638. #endif 639. }  640.   641.  makevtele 642. {  643.  	makeniche(TELEP_TRAP); 644. }  645.   646.  /* there should be one of these per trap */ 647. char    *engravings[] = {       "", "", "", "", "", 648. 				"ad ae?ar um", "?la? ?as ?er?", 649. 				"", "", ""  650.  #ifdef NEWTRAPS 651. 				,"", ""  652.  #endif 653. #ifdef SPIDERS 654. 				,""  655.  #endif 656. #ifdef NEWCLASS 657. 			, "", "ad ae?ar um" 658. #endif 659. #ifdef SPELLS 660. 				,""  661.  #endif 662. 				};  663.   664.  makeniche(trap_type) 665. int trap_type; 666. {  667.  	register struct mkroom *aroom; 668. 	register struct rm *rm; 669. 	register int vct = 8; 670. 	coord dd; 671. 	register dy,xx,yy; 672. 	register struct trap *ttmp; 673.  674.  	if(doorindex < DOORMAX) 675. 	  while(vct--) { 676. 	    aroom = &rooms[rn2(nroom-1)]; 677. 	    if(aroom->rtype != 0) continue;	/* not an ordinary room */ 678. 	    if(aroom->doorct == 1 && rn2(5)) continue; 679. 	    if(rn2(2)) { 680. 		dy = 1; 681. 		finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1); 682. 	    } else { 683. 		dy = -1; 684. 		finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1); 685. 	    }  686.  	    xx = dd.x;  687. yy = dd.y; 688. if((rm = &levl[xx][yy+dy])->typ) continue; 689. 	    if(trap_type || !rn2(4)) { 690.  691.  		rm->typ = SCORR; 692. 		rm->scrsym = STONE_SYM; 693. 		if(trap_type) { 694. 		    ttmp = maketrap(xx, yy+dy, trap_type); 695. 		    ttmp->once = 1; 696. 		    if (strlen(engravings[trap_type]) > 0) 697. 			make_engr_at(xx, yy-dy, engravings[trap_type]); 698. 		}  699.  		dosdoor(xx, yy, aroom, SDOOR); 700. 	    } else { 701. 		rm->typ = CORR; 702. 		rm->scrsym = CORR_SYM; 703. 		if(rn2(7)) 704. 		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR); 705. 		else { 706. 		    mksobj_at(SCR_TELEPORTATION, xx, yy+dy); 707. 		    if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy); 708. 		}  709.  	    }  710.  	    return; 711. 	}  712.  }  713.   714.  /* make a trap somewhere (in croom if mazeflag = 0) */ 715. mktrap(num, mazeflag, croom) 716. #ifndef REGBUG 717. register 718. #endif 719. 	 int num, mazeflag; 720. #ifndef REGBUG 721. register 722. #endif 723. 	 struct mkroom *croom; 724. {  725.  #ifndef REGBUG 726. 	register 727. #endif 728. 		 struct trap *ttmp; 729. #ifndef REGBUG 730. 	register 731. #endif 732. 		 int kind,nopierc,nomimic,fakedoor,fakegold, 733. #ifdef NEWCLASS 734. 		     nospikes, nolevltp, 735. #endif 736. 		     tryct = 0; 737. 	xchar mx,my; 738. 	extern char fut_geno[]; 739.  740.  	if(!num || num >= TRAPNUM) { 741. 		nopierc = (dlevel < 4) ? 1 : 0; 742.  #ifdef NEWCLASS 743. 		nolevltp = (dlevel < 5) ? 1 : 0; 744.  		nospikes = (dlevel < 6) ? 1 : 0; 745.  #endif 746. 		nomimic = (dlevel < 9 || goldseen ) ? 1 : 0; 747.  		if(index(fut_geno, 'M')) nomimic = 1; 748.  749.  		do { 750. 		    kind = rnd(TRAPNUM-1); 751. 			if((kind == PIERC && nopierc) ||  752.  			   (kind == MIMIC && nomimic)  753.  #ifdef SPIDERS  754.  			   || (kind == WEB)  755.  #endif  756.  #ifdef NEWCLASS  757.  			   || (kind == SPIKED_PIT && nospikes)  758.  			   || (kind == LEVEL_TELEP && nolevltp)  759.  #endif  760.  			   )  kind = NO_TRAP; 761. 		} while(kind == NO_TRAP); 762. 	} else kind = num; 763.  764.  	if(kind == MIMIC) { 765. 		register struct monst *mtmp; 766.  767.  		fakedoor = (!rn2(3) && !mazeflag); 768. 		fakegold = (!fakedoor && !rn2(2)); 769. 		if(fakegold) goldseen = TRUE; 770. 		do { 771. 			if(++tryct > 200) return; 772. 			if(fakedoor) { 773. 				/* note: fakedoor maybe on actual door */ 774. 				if(rn2(2)){ 775. 				    if(rn2(2))	mx = croom->hx+1; 776. 				    else	mx = croom->lx-1; 777. 				    my = somey; 778. 				} else { 779. 				    if(rn2(2))	my = croom->hy+1; 780. 				    else	my = croom->ly-1; 781. 				    mx = somex; 782. 				}  783.  			} else if(mazeflag) { 784. 				coord mm; 785. 				mazexy(&mm); 786. 				mx = mm.x;  787. my = mm.y; 788. } else { 789. 				mx = somex; 790. 				my = somey; 791. 			}  792.  		} while(m_at(mx,my) || levl[mx][my].typ == STAIRS); 793. 		if(mtmp = makemon(PM_MIMIC,mx,my)) { 794. 		    mtmp->mimic = 1; 795. 		    mtmp->mappearance = 796. 			fakegold ? '$' : fakedoor ? DOOR_SYM : 797. 			(mazeflag && rn2(2)) ? AMULET_SYM : 798. #ifdef SPELLS 799. 			"=/)%?![<>+" [ rn2(10) ];  800.  #else  801.  			"=/)%?![<>" [ rn2(9) ]; 802. #endif 803. 		}  804.  		return; 805. 	}  806.   807.  	do { 808. 		if(++tryct > 200) 809. 			return; 810. 		if(mazeflag){ 811. 			coord mm; 812. 			mazexy(&mm); 813. 			mx = mm.x;  814. my = mm.y; 815. } else { 816. 			mx = somex; 817. 			my = somey; 818. 		}  819.  	} while(t_at(mx, my) || levl[mx][my].typ == STAIRS); 820. 	ttmp = maketrap(mx, my, kind); 821. 	if(mazeflag && !rn2(10) && ttmp->ttyp < PIERC) 822. 		ttmp->tseen = 1; 823. }  824.   825.  #ifdef FOUNTAINS 826. mkfount(mazeflag,croom) 827. register struct mkroom *croom; 828. register mazeflag; 829. {  830.        register xchar mx,my; 831.       register int tryct = 0; 832.  833.        do { 834. 	      if(++tryct > 200) 835. 		      return; 836. 	      if(mazeflag){ 837. 		      coord mm; 838. 		      mazexy(&mm); 839. 		      mx = mm.x;  840. my = mm.y; 841. } else { 842. 		      mx = somex; 843. 		      my = somey; 844. 	      }  845.        } while(t_at(mx, my) || levl[mx][my].typ == STAIRS  846.  #ifdef NEWCLASS  847.  	      || IS_THRONE(levl[mx][my].typ)  848.  #endif  849.  	     ); 850.  851.         /* Put a fountain at mx, my */ 852.  853.         levl[mx][my].typ = FOUNTAIN; 854.        levl[mx][my].scrsym = FOUNTAIN_SYM; 855.  856.  }  857.  #endif /* FOUNTAINS /**/ 858.