Source:NetHack 1.3d/mklev.c

From NetHackWiki
Jump to navigation Jump to search

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

Screenshots and source code from Hack are used under the CWI license.

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<COLNO; x++) for(y=0; y<ROWNO; y++)
52.   		levl[x][y] = zerorm;
53.   
54.   	oinit();	/* assign level dependent obj probabilities */
55.   
56.   	if(dlevel >= 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();	/* %% < and > 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.