Source:NetHack 2.2a/mklev.c

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