Source:NetHack 1.4f/mklev.c

From NetHackWiki
Revision as of 01:10, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 1.4f/mklev.c moved to Source:NetHack 1.4f/mklev.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

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

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<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 = 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();	/* %% < and > 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.