Source:NetHack 2.3e/mklev.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to mklev.c from the source code of NetHack 2.3e.

Warning! This is the source code from an old release. For newer releases, see Source code

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

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<COLNO; x++) for(y=0; y<ROWNO; y++)
62.   		levl[x][y] = zerorm;
63.   
64.   	oinit();	/* assign level dependent obj probabilities */
65.   #ifdef RPH
66.   	if (u.wiz_level == 0) {
67.   	    u.medusa_level = rn1(3, (MAXLEVEL > 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();	/* %% < and > 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 /**/