Source:NetHack 3.0.0/mklev.c

From NetHackWiki
Revision as of 04:54, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/mklev.c moved to Source:NetHack 3.0.0/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 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mklev.c#line123]], for example.

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)mklev.c	3.0	88/11/24
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    /* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
8.    /* croom->lx etc are schar (width <= int), so % arith ensures that */
9.    /* conversion of result to int is reasonable */
10.   
11.   #ifdef SINKS
12.   static void mksink();
13.   #endif
14.   #ifdef ALTARS
15.   static void mkaltar();
16.   #endif
17.   
18.   int
19.   somex(croom)
20.   register struct mkroom *croom;
21.   {
22.   	return rn2(croom->hx-croom->lx+1) + croom->lx;
23.   }
24.   
25.   int
26.   somey(croom)
27.   register struct mkroom *croom;
28.   {
29.   	return rn2(croom->hy-croom->ly+1) + croom->ly;
30.   }
31.   
32.   #define	XLIM	4	/* define minimum required space around a room */
33.   #define	YLIM	3
34.   boolean secret;		/* TRUE while making a vault: increase [XY]LIM */
35.   struct rm zerorm;
36.   schar nxcor;
37.   boolean goldseen;
38.   
39.   /* Definitions used by makerooms() and addrs() */
40.   #define	MAXRS	50	/* max lth of temp rectangle table - arbitrary */
41.   struct rectangle {
42.   	xchar rlx,rly,rhx,rhy;
43.   } rs[MAXRS+1];
44.   int rscnt,rsmax;	/* 0..rscnt-1: currently under consideration */
45.   			/* rscnt..rsmax: discarded */
46.   
47.   static void
48.   addrsx(lx,ly,hx,hy,discarded)
49.   register int lx,ly,hx,hy;
50.   boolean discarded;		/* piece of a discarded area */
51.   {
52.   	register struct rectangle *rsp;
53.   
54.   	/* check inclusions */
55.   	for(rsp = rs; rsp < &rs[rsmax]; rsp++) {
56.   		if(lx >= rsp->rlx && hx <= rsp->rhx &&
57.   		   ly >= rsp->rly && hy <= rsp->rhy)
58.   			return;
59.   	}
60.   
61.   	/* make a new entry */
62.   	if(rsmax >= MAXRS) {
63.   #ifdef WIZARD
64.   		if(wizard) pline("MAXRS may be too small.");
65.   #endif
66.   		return;
67.   	}
68.   	rsmax++;
69.   	if(!discarded) {
70.   		*rsp = rs[rscnt];
71.   		rsp = &rs[rscnt];
72.   		rscnt++;
73.   	}
74.   	rsp->rlx = lx;
75.   	rsp->rly = ly;
76.   	rsp->rhx = hx;
77.   	rsp->rhy = hy;
78.   }
79.   
80.   static void
81.   addrs(lowx,lowy,hix,hiy)
82.   register int lowx,lowy,hix,hiy;
83.   {
84.   	register struct rectangle *rsp;
85.   	register int lx,ly,hx,hy,xlim,ylim;
86.   	boolean discarded;
87.   
88.   	xlim = XLIM + secret;
89.   	ylim = YLIM + secret;
90.   
91.   	/* walk down since rscnt and rsmax change */
92.   	for(rsp = &rs[rsmax-1]; rsp >= rs; rsp--) {
93.   
94.   		if((lx = rsp->rlx) > hix || (ly = rsp->rly) > hiy ||
95.   		   (hx = rsp->rhx) < lowx || (hy = rsp->rhy) < lowy)
96.   			continue;
97.   		if((discarded = (rsp >= &rs[rscnt]))) {
98.   			*rsp = rs[--rsmax];
99.   		} else {
100.  			rsmax--;
101.  			rscnt--;
102.  			*rsp = rs[rscnt];
103.  			if(rscnt != rsmax)
104.  				rs[rscnt] = rs[rsmax];
105.  		}
106.  		if(lowy - ly > 2*ylim + 4)
107.  			addrsx(lx,ly,hx,lowy-2,discarded);
108.  		if(lowx - lx > 2*xlim + 4)
109.  			addrsx(lx,ly,lowx-2,hy,discarded);
110.  		if(hy - hiy > 2*ylim + 4)
111.  			addrsx(lx,hiy+2,hx,hy,discarded);
112.  		if(hx - hix > 2*xlim + 4)
113.  			addrsx(hix+2,ly,hx,hy,discarded);
114.  	}
115.  }
116.  
117.  static int
118.  comp(x,y)
119.  register struct mkroom *x,*y;
120.  {
121.  	if(x->lx < y->lx) return(-1);
122.  	return(x->lx > y->lx);
123.  }
124.  
125.  static void
126.  finddpos(cc, xl,yl,xh,yh)
127.  coord	*cc;
128.  xchar	xl,yl,xh,yh;
129.  {
130.  	register xchar x, y;
131.  
132.  	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
133.  	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
134.  	if(okdoor(x, y))
135.  		goto gotit;
136.  
137.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
138.  		if(okdoor(x, y))
139.  			goto gotit;
140.  
141.  	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
142.  		if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
143.  			goto gotit;
144.  	/* cannot find something reasonable -- strange */
145.  	x = xl;
146.  	y = yh;
147.  gotit:
148.  	cc->x = x;
149.  	cc->y = y;
150.  	return;
151.  }
152.  
153.  /* Only called from makerooms() and makebigroom() */
154.  static int
155.  maker(lowx,ddx,lowy,ddy,lit)
156.  schar lowx,ddx,lowy,ddy;
157.  boolean lit;
158.  {
159.  	register struct mkroom *croom;
160.  	register int x, y, hix = lowx+ddx, hiy = lowy+ddy;
161.  	register int xlim = XLIM + secret, ylim = YLIM + secret;
162.  
163.  	if(nroom >= MAXNROFROOMS) return(0);
164.  	if(lowx < XLIM) lowx = XLIM;
165.  	if(lowy < YLIM) lowy = YLIM;
166.  	if(hix > COLNO-XLIM-1) hix = COLNO-XLIM-1;
167.  	if(hiy > ROWNO-YLIM-1) hiy = ROWNO-YLIM-1;
168.  chk:
169.  	if(hix <= lowx || hiy <= lowy) return(0);
170.  
171.  	/* check area around room (and make room smaller if necessary) */
172.  	for(x = lowx - xlim; x <= hix + xlim; x++) {
173.  		for(y = lowy - ylim; y <= hiy + ylim; y++) {
174.  			if(levl[x][y].typ) {
175.  #ifdef WIZARD
176.  			    if(wizard && !secret)
177.  				pline("Strange area [%d,%d] in maker().",x,y);
178.  #endif
179.  				if(!rn2(3)) return(0);
180.  				if(x < lowx)
181.  					lowx = x+xlim+1;
182.  				else
183.  					hix = x-xlim-1;
184.  				if(y < lowy)
185.  					lowy = y+ylim+1;
186.  				else
187.  					hiy = y-ylim-1;
188.  				goto chk;
189.  			}
190.  		}
191.  	}
192.  
193.  	croom = &rooms[nroom];
194.  
195.  	/* on low levels the room is lit (usually) */
196.  	/* secret vaults are always lit */
197.  	/* some other rooms may require lighting */
198.  	if((rnd(dlevel) < 10 && rn2(77)) || secret || lit) {
199.  		for(x = lowx-1; x <= hix+1; x++)
200.  			for(y = lowy-1; y <= hiy+1; y++)
201.  				levl[x][y].lit = 1;
202.  		croom->rlit = 1;
203.  	} else
204.  		croom->rlit = 0;
205.  	croom->lx = lowx;
206.  	croom->hx = hix;
207.  	croom->ly = lowy;
208.  	croom->hy = hiy;
209.  	croom->rtype = OROOM;
210.  	croom->doorct = 0;
211.  	/* if we're not making a vault, doorindex will still be 0
212.  	 * if we are, we'll have problems adding niches to the previous room
213.  	 * unless fdoor is at least doorindex
214.  	 */
215.  	croom->fdoor = doorindex;
216.  
217.  	for(x = lowx-1; x <= hix+1; x++)
218.  	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
219.  		levl[x][y].typ = HWALL;
220.  		levl[x][y].scrsym = HWALL_SYM;
221.  	    }
222.  	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
223.  	    for(y = lowy; y <= hiy; y++) {
224.  		levl[x][y].typ = VWALL;
225.  		levl[x][y].scrsym = VWALL_SYM;
226.  	    }
227.  	for(x = lowx; x <= hix; x++)
228.  	    for(y = lowy; y <= hiy; y++) {
229.  		levl[x][y].typ = ROOM;
230.  		levl[x][y].scrsym = ROOM_SYM;
231.  	    }
232.  	levl[lowx-1][lowy-1].typ = TLCORNER;
233.  	levl[hix+1][lowy-1].typ = TRCORNER;
234.  	levl[lowx-1][hiy+1].typ = BLCORNER;
235.  	levl[hix+1][hiy+1].typ = BRCORNER;
236.  	levl[lowx-1][lowy-1].scrsym = TLCORN_SYM;
237.  	levl[hix+1][lowy-1].scrsym = TRCORN_SYM;
238.  	levl[lowx-1][hiy+1].scrsym = BLCORN_SYM;
239.  	levl[hix+1][hiy+1].scrsym = BRCORN_SYM;
240.  
241.  	smeq[nroom] = nroom;
242.  	croom++;
243.  	croom->hx = -1;
244.  	nroom++;
245.  	return(1);
246.  }
247.  
248.  static int
249.  makerooms() {
250.  register struct rectangle *rsp;
251.  register int lx, ly, hx, hy, lowx, lowy, hix, hiy, dx, dy;
252.  int tryct = 0, xlim, ylim;
253.  
254.  	/* init */
255.  	xlim = XLIM + secret;
256.  	ylim = YLIM + secret;
257.  	if(nroom == 0) {
258.  		rsp = rs;
259.  		rsp->rlx = rsp->rly = 0;
260.  		rsp->rhx = COLNO-1;
261.  		rsp->rhy = ROWNO-1;
262.  		rsmax = 1;
263.  	}
264.  	rscnt = rsmax;
265.  
266.  	/* make rooms until satisfied */
267.  	while(rscnt > 0 && nroom < MAXNROFROOMS-1) {
268.  		if(!secret && nroom > (MAXNROFROOMS/4) &&
269.  		   !rn2((MAXNROFROOMS-nroom)*(MAXNROFROOMS-nroom)))
270.  			return 0;
271.  
272.  		/* pick a rectangle */
273.  		rsp = &rs[rn2(rscnt)];
274.  		hx = rsp->rhx;
275.  		hy = rsp->rhy;
276.  		lx = rsp->rlx;
277.  		ly = rsp->rly;
278.  
279.  		/* find size of room */
280.  		if(secret)
281.  			dx = dy = 1;
282.  		else {
283.  			dx = 2 + rn2((hx-lx-8 > 20) ? 12 : 8);
284.  			dy = 2 + rn2(4);
285.  			if(dx*dy > 50)
286.  				dy = 50/dx;
287.  		}
288.  
289.  		/* look whether our room will fit */
290.  		if(hx-lx < dx + (dx>>1) + 2*xlim ||
291.  		   hy-ly < dy + dy/3 + 2*ylim) {
292.  					/* no, too small */
293.  					/* maybe we throw this area out */
294.  			if(secret || !rn2(MAXNROFROOMS+1-nroom-tryct)) {
295.  				rscnt--;
296.  				rs[rsmax] = *rsp;
297.  				*rsp = rs[rscnt];
298.  				rs[rscnt] = rs[rsmax];
299.  				tryct = 0;
300.  			} else
301.  				tryct++;
302.  			continue;
303.  		}
304.  
305.  		lowx = lx + xlim + rn2(hx - lx - dx - 2*xlim + 1);
306.  		lowy = ly + ylim + rn2(hy - ly - dy - 2*ylim + 1);
307.  		hix = lowx + dx;
308.  		hiy = lowy + dy;
309.  
310.  		if(maker(lowx, dx, lowy, dy, FALSE)) {
311.  			if(secret) return(1);
312.  			addrs(lowx-1, lowy-1, hix+1, hiy+1);
313.  			tryct = 0;
314.  		} else
315.  			if(tryct++ > 100)
316.  				break;
317.  	}
318.  	return(0);	/* failed to make vault - very strange */
319.  }
320.  
321.  static void
322.  join(a,b)
323.  register int a, b;
324.  {
325.  	coord cc,tt;
326.  	register int tx, ty, xx, yy;
327.  	register struct rm *crm;
328.  	register struct mkroom *croom, *troom;
329.  	register int dx, dy, dix, diy, cct;
330.  
331.  	croom = &rooms[a];
332.  	troom = &rooms[b];
333.  
334.  	/* find positions cc and tt for doors in croom and troom
335.  	   and direction for a corridor between them */
336.  
337.  	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
338.  	if(troom->lx > croom->hx) {
339.  		dx = 1;
340.  		dy = 0;
341.  		xx = croom->hx+1;
342.  		tx = troom->lx-1;
343.  		finddpos(&cc, xx, croom->ly, xx, croom->hy);
344.  		finddpos(&tt, tx, troom->ly, tx, troom->hy);
345.  	} else if(troom->hy < croom->ly) {
346.  		dy = -1;
347.  		dx = 0;
348.  		yy = croom->ly-1;
349.  		finddpos(&cc, croom->lx, yy, croom->hx, yy);
350.  		ty = troom->hy+1;
351.  		finddpos(&tt, troom->lx, ty, troom->hx, ty);
352.  	} else if(troom->hx < croom->lx) {
353.  		dx = -1;
354.  		dy = 0;
355.  		xx = croom->lx-1;
356.  		tx = troom->hx+1;
357.  		finddpos(&cc, xx, croom->ly, xx, croom->hy);
358.  		finddpos(&tt, tx, troom->ly, tx, troom->hy);
359.  	} else {
360.  		dy = 1;
361.  		dx = 0;
362.  		yy = croom->hy+1;
363.  		ty = troom->ly-1;
364.  		finddpos(&cc, croom->lx, yy, croom->hx, yy);
365.  		finddpos(&tt, troom->lx, ty, troom->hx, ty);
366.  	}
367.  	xx = cc.x;
368.  	yy = cc.y;
369.  	tx = tt.x - dx;
370.  	ty = tt.y - dy;
371.  	if(nxcor && levl[xx+dx][yy+dy].typ)
372.  		return;
373.  	dodoor(xx,yy,croom);
374.  
375.  	cct = 0;
376.  	while(xx != tx || yy != ty) {
377.  	    xx += dx;
378.  	    yy += dy;
379.  
380.  	    /* loop: dig corridor at [xx,yy] and find new [xx,yy] */
381.  	    if(cct++ > 500 || (nxcor && !rn2(35)))
382.  		return;
383.  
384.  	    if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1)
385.  		return;		/* impossible */
386.  
387.  	    crm = &levl[xx][yy];
388.  	    if(!(crm->typ)) {
389.  		if(rn2(100)) {
390.  			crm->typ = CORR;
391.  			crm->scrsym = CORR_SYM;
392.  			if(nxcor && !rn2(50))
393.  				(void) mksobj_at(BOULDER, xx, yy);
394.  		} else {
395.  			crm->typ = SCORR;
396.  			crm->scrsym = STONE_SYM;
397.  		}
398.  	    } else
399.  	    if(crm->typ != CORR && crm->typ != SCORR) {
400.  		/* strange ... */
401.  		return;
402.  	    }
403.  
404.  	    /* find next corridor position */
405.  	    dix = abs(xx-tx);
406.  	    diy = abs(yy-ty);
407.  
408.  	    /* do we have to change direction ? */
409.  	    if(dy && dix > diy) {
410.  		register int ddx = (xx > tx) ? -1 : 1;
411.  
412.  		crm = &levl[xx+ddx][yy];
413.  		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
414.  		    dx = ddx;
415.  		    dy = 0;
416.  		    continue;
417.  		}
418.  	    } else if(dx && diy > dix) {
419.  		register int ddy = (yy > ty) ? -1 : 1;
420.  
421.  		crm = &levl[xx][yy+ddy];
422.  		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) {
423.  		    dy = ddy;
424.  		    dx = 0;
425.  		    continue;
426.  		}
427.  	    }
428.  
429.  	    /* continue straight on? */
430.  	    crm = &levl[xx+dx][yy+dy];
431.  	    if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
432.  		continue;
433.  
434.  	    /* no, what must we do now?? */
435.  	    if(dx) {
436.  		dx = 0;
437.  		dy = (ty < yy) ? -1 : 1;
438.  		crm = &levl[xx+dx][yy+dy];
439.  		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
440.  		    continue;
441.  		dy = -dy;
442.  		continue;
443.  	    } else {
444.  		dy = 0;
445.  		dx = (tx < xx) ? -1 : 1;
446.  		crm = &levl[xx+dx][yy+dy];
447.  		if(!crm->typ || crm->typ == CORR || crm->typ == SCORR)
448.  		    continue;
449.  		dx = -dx;
450.  		continue;
451.  	    }
452.  	}
453.  
454.  	/* we succeeded in digging the corridor */
455.  	dodoor(tt.x, tt.y, troom);
456.  
457.  	if(smeq[a] < smeq[b])
458.  		smeq[b] = smeq[a];
459.  	else
460.  		smeq[a] = smeq[b];
461.  }
462.  
463.  static void
464.  makecorridors() {
465.  	register int a, b;
466.  
467.  	nxcor = 0;
468.  	for(a = 0; a < nroom-1; a++)
469.  		join(a, a+1);
470.  	for(a = 0; a < nroom-2; a++)
471.  	    if(smeq[a] != smeq[a+2])
472.  		join(a, a+2);
473.  	for(a = 0; a < nroom; a++)
474.  	    for(b = 0; b < nroom; b++)
475.  		if(smeq[a] != smeq[b])
476.  		    join(a, b);
477.  	if(nroom > 2)
478.  	    for(nxcor = rn2(nroom) + 4; nxcor; nxcor--) {
479.  		a = rn2(nroom);
480.  		b = rn2(nroom-2);
481.  		if(b >= a) b += 2;
482.  		join(a, b);
483.  	    }
484.  }
485.  
486.  static void
487.  dosdoor(x,y,aroom,type)
488.  register int x, y;
489.  register struct mkroom *aroom;
490.  register int type;
491.  {
492.  	register struct mkroom *broom;
493.  	register int tmp;
494.  	boolean shdoor = in_shop(x, y);
495.  
496.  	if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs with DOOR_SYM as scrsym */
497.  		type = DOOR;
498.  	levl[x][y].typ = type;
499.  	if(type == DOOR) {
500.  	    levl[x][y].scrsym = DOOR_SYM;
501.  	    if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */
502.  		if(!rn2(5))
503.  		    levl[x][y].doormask = D_ISOPEN;
504.  		else if(!rn2(4))
505.  		    levl[x][y].doormask = D_LOCKED;
506.  		else
507.  		    levl[x][y].doormask = D_CLOSED;
508.  
509.  		if (levl[x][y].doormask != D_ISOPEN && !shdoor && !rn2(25))
510.  		    levl[x][y].doormask |= D_TRAPPED;
511.  	    } else {
512.  		if(shdoor)	levl[x][y].doormask = D_ISOPEN;
513.  		else		levl[x][y].doormask = D_NODOOR;
514.  	    }
515.  	} else { /* SDOOR */
516.  		if(shdoor || !rn2(5))	levl[x][y].doormask = D_LOCKED;
517.  		else			levl[x][y].doormask = D_CLOSED;
518.  
519.  		if(!shdoor && !rn2(20)) levl[x][y].doormask |= D_TRAPPED;
520.  	}
521.  	aroom->doorct++;
522.  	broom = aroom+1;
523.  	if(broom->hx < 0) tmp = doorindex; else
524.  	for(tmp = doorindex; tmp > broom->fdoor; tmp--)
525.  		doors[tmp] = doors[tmp-1];
526.  	doorindex++;
527.  	doors[tmp].x = x;
528.  	doors[tmp].y = y;
529.  	for( ; broom->hx >= 0; broom++) broom->fdoor++;
530.  }
531.  
532.  static boolean
533.  place_niche(aroom,dy,xx,yy)
534.  register struct mkroom *aroom;
535.  int *dy, *xx, *yy;
536.  {
537.  	coord dd;
538.  
539.  	if(rn2(2)) {
540.  	    *dy = 1;
541.  	    finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
542.  	} else {
543.  	    *dy = -1;
544.  	    finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
545.  	}
546.  	*xx = dd.x;
547.  	*yy = dd.y;
548.  	return(levl[*xx][(*yy)+(*dy)].typ == STONE);
549.  }
550.  
551.  #ifdef ORACLE
552.  boolean
553.  place_oracle(aroom,dy,xx,yy)
554.  register struct mkroom *aroom;
555.  int *dy, *xx, *yy;
556.  {
557.  	if(!place_niche(aroom,dy,xx,yy)) return FALSE;
558.  
559.  	dosdoor(*xx,*yy,aroom,DOOR);
560.  	levl[*xx][*yy].doormask = D_NODOOR;
561.  	return TRUE;
562.  }
563.  #endif
564.  
565.  /* there should be one of these per trap */
566.  const char *engravings[] = {	"", "", "", "", "", "",
567.  				"?la? ?as ?er?", "ad ae?ar um",
568.  				"", "", "", "" ,""
569.  				, "", "ad ae?ar um"
570.  #ifdef SPELLS
571.  				,""
572.  #endif
573.  				,""
574.  #ifdef POLYSELF
575.  				,""
576.  #endif
577.  				,""
578.  				};
579.  
580.  static void
581.  makeniche(trap_type)
582.  int trap_type;
583.  {
584.  	register struct mkroom *aroom;
585.  	register struct rm *rm;
586.  	register int vct = 8;
587.  	int dy, xx, yy;
588.  	register struct trap *ttmp;
589.  
590.  	if(doorindex < DOORMAX)
591.  	  while(vct--) {
592.  	    aroom = &rooms[rn2(nroom)];
593.  	    if(aroom->rtype != OROOM) continue;	/* not an ordinary room */
594.  	    if(aroom->doorct == 1 && rn2(5)) continue;
595.  	    if(!place_niche(aroom,&dy,&xx,&yy)) continue;
596.  
597.  	    rm = &levl[xx][yy+dy];
598.  	    if(trap_type || !rn2(4)) {
599.  
600.  		rm->typ = SCORR;
601.  		rm->scrsym = STONE_SYM;
602.  		if(trap_type) {
603.  		    ttmp = maketrap(xx, yy+dy, trap_type);
604.  		    ttmp->once = 1;
605.  		    if (strlen(engravings[trap_type]) > 0)
606.  			make_engr_at(xx, yy-dy, engravings[trap_type]);
607.  		}
608.  		dosdoor(xx, yy, aroom, SDOOR);
609.  	    } else {
610.  		rm->typ = CORR;
611.  		rm->scrsym = CORR_SYM;
612.  		if(rn2(7))
613.  		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
614.  		else {
615.  		    (void) mksobj_at(SCR_TELEPORTATION, xx, yy+dy);
616.  		    if(!rn2(3)) (void) mkobj_at(0, xx, yy+dy);
617.  		}
618.  	    }
619.  	    return;
620.  	}
621.  }
622.  
623.  static void
624.  make_niches()
625.  {
626.  	register int ct = rnd((nroom>>1) + 1);
627.  	boolean	ltptr = TRUE,
628.  		vamp = TRUE;
629.  
630.  	while(ct--) {
631.  
632.  		if(dlevel > 15 && !rn2(6) && ltptr) {
633.  
634.  			ltptr = FALSE;
635.  			makeniche(LEVEL_TELEP);
636.  		} else if (dlevel > 5 && dlevel < 25
637.  			   && !rn2(6) && vamp) {
638.  
639.  			vamp = FALSE;
640.  			makeniche(TRAPDOOR);
641.  		} else	makeniche(NO_TRAP);
642.  	}
643.  }
644.  
645.  static void
646.  makebigroom()
647.  {
648.  	register int x,y,n;
649.  	register struct mkroom *croom;
650.  	register struct monst *tmonst;
651.  
652.  	/* make biggest possible room; make sure it's lit */
653.  	(void) maker(XLIM, COLNO - 2*XLIM - 1, YLIM, ROWNO - 2*YLIM - 1, TRUE);
654.  	croom = &rooms[0];
655.  
656.  	/* add extra monsters and goodies */
657.  	n = 10 + rn2(15);
658.  	while (n--) {
659.  		x = somex(croom);
660.  		y = somey(croom);
661.  		tmonst = makemon((struct permonst *) 0,x,y);
662.  		if (tmonst && tmonst->data==&mons[PM_GIANT_SPIDER])
663.  			(void) maketrap(x,y,WEB);
664.  		if (tmonst && rn2(2))
665.  			tmonst->msleep = 1;
666.  	}
667.  	n = 6 + rn2(10);
668.  	while (n--)
669.  		(void) mkobj_at(0,somex(croom),somey(croom));
670.  }
671.  
672.  static void
673.  makevtele()
674.  {
675.  	makeniche(TELEP_TRAP);
676.  }
677.  
678.  #define rntwixt(L1,L2)	rn1((L2)-(L1),L1)
679.  
680.  static void
681.  init_levels()
682.  {
683.  #if defined(STRONGHOLD) && defined(MUSIC)
684.  	register int x;
685.  #endif
686.  
687.  #ifdef LINT	/* handle constant in conditional context */
688.  	medusa_level = 0;
689.  #else
690.  	medusa_level = rn1(3, HELLLEVEL - 5);
691.  #endif /* LINT */
692.  #ifdef STRONGHOLD
693.  	stronghold_level = rn1(5, medusa_level)+1;
694.  # ifdef MUSIC
695.  	for (x=0; x<5; x++)
696.  		tune[x] = 'A' + rn2(7);
697.  	tune[5] = 0;
698.  # endif
699.  	/* The tower will be on 3 levels */
700.  	tower_level = rntwixt(stronghold_level, MAXLEVEL-2)+1;
701.  	/* We don't want the wizard in Vlad's tower */
702.  	do
703.  		wiz_level = rntwixt(stronghold_level, MAXLEVEL)+1;
704.  	while (wiz_level >= tower_level && wiz_level <= tower_level + 2);
705.  #else
706.  	wiz_level	 = rntwixt(medusa_level, MAXLEVEL)+1;
707.  #endif /* STRONGHOLD /**/
708.  #ifdef WIZARD
709.  	if (!rn2(15) || wizard)
710.  #else
711.  	if (!rn2(15))
712.  #endif
713.  		/* between the middle of the dungeon and the medusa level */
714.  		bigroom_level = rntwixt(HELLLEVEL>>1, medusa_level);
715.  #ifdef REINCARNATION
716.  # ifdef WIZARD
717.  	if (!rn2(3) || wizard)
718.  # else
719.  	if (!rn2(3))
720.  # endif
721.  		rogue_level = rn1(5,10);
722.  #endif
723.  #ifdef ORACLE
724.  	oracle_level = rn1(4,5);
725.  #endif
726.  }
727.  
728.  #undef rntwixt
729.  
730.  static void
731.  makelevel() {
732.  	register struct mkroom *croom, *troom;
733.  	register unsigned int tryct;
734.  	register int x,y;
735.  	struct monst *tmonst;	/* always put a web with a spider */
736.  
737.  	nroom = 0;
738.  	doorindex = 0;
739.  	rooms[0].hx = -1;	/* in case we are in a maze */
740.  
741.  	for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++)
742.  		levl[x][y] = zerorm;
743.  
744.  	oinit();	/* assign level dependent obj probabilities */
745.  	fountsound = 0;
746.  	sinksound = 0;
747.  
748.  	if (wiz_level == 0)
749.  		init_levels();
750.  	if (
751.  #ifndef STRONGHOLD
752.  	    Inhell
753.  #else
754.  	    dlevel >= stronghold_level || dlevel < 0
755.  #endif
756.  	    || (dlevel > medusa_level && rn2(5))
757.  	   ) {
758.  	    makemaz();
759.  	    return;
760.  	}
761.  
762.  	/* construct the rooms */
763.  	nroom = 0;
764.  	secret = FALSE;
765.  
766.  #ifdef REINCARNATION
767.  	if (dlevel == rogue_level) {
768.  	    makeroguerooms();
769.  	    makerogueghost();
770.  	} else
771.  #endif
772.  	if (dlevel == bigroom_level)
773.  	    makebigroom();
774.  	else
775.  	    (void) makerooms();
776.  
777.  	/* construct stairs (up and down in different rooms if possible) */
778.  	croom = &rooms[rn2(nroom)];
779.  	xdnstair = somex(croom);
780.  	ydnstair = somey(croom);
781.  	levl[xdnstair][ydnstair].scrsym = DN_SYM;
782.  	levl[xdnstair][ydnstair].typ = STAIRS;
783.  #ifdef MEDUSA
784.  	if (dlevel == medusa_level) {
785.  		struct monst *mtmp;
786.  
787.  		if (mtmp = makemon(&mons[PM_MEDUSA], xdnstair, ydnstair))
788.  			mtmp->msleep = 1;
789.  		for (tryct = rn1(1,3); tryct; tryct--) {
790.  			x = somex(croom); y = somey(croom);
791.  			if (goodpos(x,y))
792.  				(void) mk_tt_statue(x, y);
793.  		}
794.  	}
795.  #endif
796.  	if(nroom > 1) {
797.  		troom = croom;
798.  		croom = &rooms[rn2(nroom-1)];
799.  		if(croom >= troom) croom++;
800.  	}
801.  	xupstair = somex(croom);    /* %% < and > might be in the same place */
802.  	yupstair = somey(croom);
803.  	levl[xupstair][yupstair].scrsym = UP_SYM;
804.  	levl[xupstair][yupstair].typ = STAIRS;
805.  #ifdef STRONGHOLD
806.  	xdnladder = ydnladder = xupladder = yupladder = 0;
807.  #endif
808.  	is_maze_lev = FALSE;
809.  
810.  #ifdef SYSV
811.  	qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), comp);
812.  #else
813.  	qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), comp);
814.  #endif
815.  #ifdef REINCARNATION
816.  	if (dlevel == rogue_level) {
817.  	   You("feel as though you were here in a previous lifetime.");
818.  	   return;
819.  	}
820.  #endif
821.  	makecorridors();
822.  	make_niches();
823.  
824.  	/* make a secret treasure vault, not connected to the rest */
825.  	if(nroom <= (MAXNROFROOMS/2)) if(rn2(3)) {
826.  
827.  		troom = &rooms[nroom];
828.  		secret = TRUE;
829.  		if(makerooms()) {
830.  			troom->rtype = VAULT;		/* treasure vault */
831.  			for(x = troom->lx; x <= troom->hx; x++)
832.  			for(y = troom->ly; y <= troom->hy; y++)
833.  				mkgold((long)(rnd(dlevel*100) + 50), x, y);
834.  			if(!rn2(3))
835.  				makevtele();
836.  		}
837.  	}
838.  
839.  #ifdef WIZARD
840.  	if(wizard && getenv("SHOPTYPE")) mkroom(SHOPBASE); else
841.  #endif
842.  #ifdef ORACLE
843.  	if(dlevel == oracle_level) mkroom(DELPHI);
844.  	/*  It is possible that we find no good place to set up Delphi.
845.  	 *  It is also possible to get more than one Delphi using bones levels.
846.  	 *  The first is not a problem; the second is a minor nuisance.
847.  	 */
848.  	else
849.  #endif
850.  	if(dlevel > 1 && dlevel < medusa_level && rn2(dlevel) < 3) mkroom(SHOPBASE);
851.  	else
852.  #ifdef THRONES
853.  	if(dlevel > 4 && !rn2(6)) mkroom(COURT);
854.  	else
855.  #endif
856.  	if(dlevel > 6 && !rn2(7)) mkroom(ZOO);
857.  	else
858.  #ifdef ALTARS
859.  	if(dlevel > 8 && !rn2(5)) mkroom(TEMPLE);
860.  	else
861.  #endif
862.  	if(dlevel > 9 && !rn2(5) && !(mons[PM_KILLER_BEE].geno & G_GENOD))
863.  		mkroom(BEEHIVE);
864.  	else
865.  	if(dlevel > 11 && !rn2(6)) mkroom(MORGUE);
866.  	else
867.  #ifdef ARMY
868.  	if(dlevel > 14 && !rn2(4) && !(mons[PM_SOLDIER].geno & G_GENOD))
869.  		mkroom(BARRACKS);
870.  	else
871.  #endif
872.  	if(dlevel > 18 && !rn2(6)) mkroom(SWAMP);
873.  
874.  
875.  	/* for each room: put things inside */
876.  	for(croom = rooms; croom->hx > 0; croom++) {
877.  		register boolean boxinlev = FALSE;
878.  
879.  		if(croom->rtype != OROOM) continue;
880.  
881.  		/* put a sleeping monster inside */
882.  		/* Note: monster may be on the stairs. This cannot be
883.  		   avoided: maybe the player fell through a trapdoor
884.  		   while a monster was on the stairs. Conclusion:
885.  		   we have to check for monsters on the stairs anyway. */
886.  
887.  		if(u.uhave_amulet || !rn2(3)) {
888.  		    x = somex(croom); y = somey(croom);
889.  #ifdef REINCARNATION
890.  		    if (dlevel == rogue_level)
891.  			tmonst = makemon(roguemon(), x, y);
892.  		    else
893.  #endif
894.  		    tmonst = makemon((struct permonst *) 0, x,y);
895.  		    if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER])
896.  			(void) maketrap (x,y,WEB);
897.  		}
898.  		/* put traps and mimics inside */
899.  		goldseen = FALSE;
900.  		while(!rn2(8-(dlevel/6))) mktrap(0,0,croom);
901.  		if(!goldseen && !rn2(3)) mkgold(0L, somex(croom), somey(croom));
902.  #ifdef REINCARNATION
903.  		if (dlevel == rogue_level) goto skip_nonrogue;
904.  #endif
905.  #ifdef FOUNTAINS
906.  		if(!rn2(10)) mkfount(0,croom);
907.  #endif
908.  #ifdef SINKS
909.  		if(!rn2(60)) mksink(croom);
910.  #endif
911.  #ifdef ALTARS
912.  		if(!rn2(60)) mkaltar(croom);
913.  #endif
914.  		/* put statues inside */
915.  #ifdef MEDUSA
916.  		if(!rn2(dlevel == medusa_level ? 1 : 20)) {
917.  			if (!rn2(dlevel == medusa_level ? 2 : 50))
918.  				(void) mk_tt_statue(somex(croom), somey(croom));
919.  			else {
920.  				struct obj *otmp =
921.  					mkstatue((struct permonst *)0,
922.  						somex(croom), somey(croom));
923.  				if (dlevel == medusa_level && otmp) 
924.  					otmp->spe = 0;
925.  				/* Medusa statues don't contain books */
926.  			}
927.  		}
928.  #else
929.  		if(!rn2(20))
930.  				(void) mkstatue((struct permonst *)0,
931.  						somex(croom), somey(croom));
932.  #endif
933.  
934.  		/* put box/chest inside */
935.  		if(!rn2(20) && !boxinlev) {
936.  
937.  		    boxinlev = TRUE;
938.  		    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
939.  				     somex(croom), somey(croom));
940.  		}
941.  
942.  #ifdef REINCARNATION
943.  	skip_nonrogue:
944.  #endif
945.  		if(!rn2(3)) {
946.  			(void) mkobj_at(0, somex(croom), somey(croom));
947.  			tryct = 0;
948.  			while(!rn2(5)) {
949.  				if(++tryct > 100){
950.  					Printf("tryct overflow4\n");
951.  					break;
952.  				}
953.  				(void) mkobj_at(0, somex(croom), somey(croom));
954.  			}
955.  		}
956.  	}
957.  }
958.  
959.  void
960.  mklev()
961.  {
962.  	if(getbones()) return;
963.  
964.  	in_mklev = TRUE;
965.  	makelevel();
966.  	bound_digging();
967.  	in_mklev = FALSE;
968.  }
969.  
970.  static boolean
971.  bydoor(x, y)
972.  register xchar x, y;
973.  {
974.  	register boolean tmp1, tmp2;
975.  
976.  	/* break up large expression to help some compilers */
977.  	tmp1 = (IS_DOOR(levl[x+1][y].typ) || levl[x+1][y].typ == SDOOR ||
978.  		IS_DOOR(levl[x-1][y].typ) || levl[x-1][y].typ == SDOOR);
979.  	tmp2 = (IS_DOOR(levl[x][y+1].typ) || levl[x][y+1].typ == SDOOR ||
980.  		IS_DOOR(levl[x][y-1].typ) || levl[x][y-1].typ == SDOOR);
981.  	return(tmp1 || tmp2);
982.  }
983.  
984.  /* see whether it is allowable to create a door at [x,y] */
985.  int
986.  okdoor(x,y)
987.  register xchar x, y;
988.  {
989.  	register boolean near_door = bydoor(x, y);
990.  
991.  	return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
992.  	   		doorindex < DOORMAX && !near_door);
993.  }
994.  
995.  void
996.  dodoor(x,y,aroom)
997.  register int x, y;
998.  register struct mkroom *aroom;
999.  {
1000. 	if(doorindex >= DOORMAX) {
1001. 		impossible("DOORMAX exceeded?");
1002. 		return;
1003. 	}
1004. 	if(!okdoor(x,y) && nxcor)
1005. 		return;
1006. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
1007. }
1008. 
1009. static boolean
1010. occupied(x, y)
1011. register xchar x, y;
1012. {
1013. 	return(t_at(x, y) || levl[x][y].typ == STAIRS
1014. #ifdef FOUNTAINS
1015. 		|| IS_FOUNTAIN(levl[x][y].typ)
1016. #endif
1017. #ifdef THRONES
1018. 		|| IS_THRONE(levl[x][y].typ)
1019. #endif
1020. #ifdef SINKS
1021. 		|| IS_SINK(levl[x][y].typ)
1022. #endif
1023. #ifdef ALTARS
1024. 		|| levl[x][y].typ == ALTAR
1025. #endif
1026. 		);
1027. }
1028. 
1029. /* make a trap somewhere (in croom if mazeflag = 0) */
1030. void
1031. mktrap(num, mazeflag, croom)
1032. register int num, mazeflag;
1033. register struct mkroom *croom;
1034. {
1035. 	register struct trap *ttmp;
1036. 	register int kind,nomonst,nomimic,nospider,
1037. #ifdef POLYSELF
1038. 		    nopoly,
1039. #endif
1040. 		    nospikes, nolevltp,
1041. 		    nolandmine,
1042. 		    tryct = 0;
1043. 
1044. 	xchar mx,my;
1045. 
1046. 	if(!num || num >= TRAPNUM) {
1047. 		nomonst = (dlevel < 4) ? 1 : 0;
1048. 		nolevltp = (dlevel < 5) ? 1 : 0;
1049. 		nospikes = (dlevel < 6) ? 1 : 0;
1050. 		nospider = (dlevel < 7) ? 1 : 0;
1051. #ifdef POLYSELF
1052. 		nopoly = (dlevel < 6) ? 1 : 0;
1053. #endif
1054. 		nolandmine = (dlevel < 5) ? 1 : 0;
1055. 		nomimic = (dlevel < 9 || goldseen ) ? 1 : 0;
1056. 		if((mons[PM_SMALL_MIMIC].geno & G_GENOD) &&
1057. 		   (mons[PM_LARGE_MIMIC].geno & G_GENOD) &&
1058. 		   (mons[PM_GIANT_MIMIC].geno & G_GENOD))
1059. 			nomimic = 1;
1060. 		if(mons[PM_GIANT_SPIDER].geno & G_GENOD)
1061. 			nospider = 1;
1062. 
1063. 		do {
1064. #ifdef REINCARNATION
1065. 		    if (dlevel==rogue_level) {
1066. 			switch(rn2(7)) {
1067. 			     case 0: kind = BEAR_TRAP; break;
1068. 			     case 1: kind = ARROW_TRAP; break;
1069. 			     case 2: kind = DART_TRAP; break;
1070. 			     case 3: kind = TRAPDOOR; break;
1071. 			     case 4: kind = PIT; break;
1072. 			     case 5: kind = SLP_GAS_TRAP; break;
1073. 			     case 6: kind = RUST_TRAP; break;
1074. 			}
1075. 		    } else
1076. #endif
1077. 			    kind = rnd(TRAPNUM-1);
1078. 		    if((kind == MONST_TRAP && (nomonst && nomimic))
1079. 			|| ((kind == WEB) && nospider)
1080. 			|| (kind == SPIKED_PIT && nospikes)
1081. 			|| (kind == LEVEL_TELEP && nolevltp)
1082. #ifdef POLYSELF
1083. 			|| (kind == POLY_TRAP && nopoly)
1084. #endif
1085. 			|| (kind == LANDMINE && nolandmine)
1086. 			)  kind = NO_TRAP;
1087. 		} while(kind == NO_TRAP);
1088. 	} else kind = num;
1089. 
1090. 	if(kind == MONST_TRAP && !nomimic && !rn2(4) && !mazeflag) {
1091. 		register struct monst *mtmp;
1092. 
1093. 		do {
1094. 			if(++tryct > 200) return;
1095. 			/* note: fakedoor maybe on actual door */
1096. 			if(rn2(2)){
1097. 			    if(rn2(2))	mx = croom->hx+1;
1098. 			    else	mx = croom->lx-1;
1099. 			    my = somey(croom);
1100. 			} else {
1101. 			    if(rn2(2))	my = croom->hy+1;
1102. 			    else	my = croom->ly-1;
1103. 			    mx = somex(croom);
1104. 			}
1105. 		} while(levl[mx][my].mmask);
1106. 
1107. 		if((mtmp = makemon(mkclass(S_MIMIC), mx, my))) {
1108. 		    mtmp->mimic = 1;
1109. 		    mtmp->mappearance = DOOR_SYM;
1110. 		}
1111. 		return;
1112. 	}
1113. 
1114. 	do {
1115. 		if(++tryct > 200)
1116. 			return;
1117. 		if(mazeflag){
1118. 			coord mm;
1119. 			mazexy(&mm);
1120. 			mx = mm.x;
1121. 			my = mm.y;
1122. 		} else {
1123. 			mx = somex(croom);
1124. 			my = somey(croom);
1125. 		}
1126. 	} while(occupied(mx, my));
1127. 
1128. 	ttmp = maketrap(mx, my, kind);
1129. 	if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER], mx, my);
1130. 	if(mazeflag && !rn2(10) && ttmp->ttyp < MONST_TRAP)
1131. 		ttmp->tseen = 1;
1132. }
1133. 
1134. #ifdef FOUNTAINS
1135. void
1136. mkfount(mazeflag,croom)
1137. register struct mkroom *croom;
1138. register int mazeflag;
1139. {
1140. 	register xchar mx,my;
1141. 	register int tryct = 0;
1142. 
1143. 	do {
1144. 	    if(++tryct > 200) return;
1145. 	    if(mazeflag) {
1146. 		 coord mm;
1147. 		 mazexy(&mm);
1148. 		 mx = mm.x;
1149. 		 my = mm.y;
1150. 	    } else {
1151. 		 mx = somex(croom);
1152. 		 my = somey(croom);
1153. 	    }
1154. 	} while(occupied(mx, my) || bydoor(mx, my));
1155. 
1156. 	/* Put a fountain at mx, my */
1157. 	levl[mx][my].typ = FOUNTAIN;
1158. 	levl[mx][my].scrsym = FOUNTAIN_SYM;
1159. 
1160. 	fountsound++;
1161. }
1162. #endif /* FOUNTAINS /**/
1163. 
1164. #ifdef SINKS
1165. static void
1166. mksink(croom)
1167. register struct mkroom *croom;
1168. {
1169. 	register xchar mx,my;
1170. 	register int tryct = 0;
1171. 
1172. 	do {
1173. 	    if(++tryct > 200) return;
1174. 	    mx = somex(croom);
1175. 	    my = somey(croom);
1176. 	} while(occupied(mx, my) || bydoor(mx, my));
1177. 
1178. 	/* Put a sink at mx, my */
1179. 	levl[mx][my].typ = SINK;
1180. 	levl[mx][my].scrsym = SINK_SYM;
1181. 
1182. 	sinksound++;
1183. }
1184. #endif /* SINKS /**/
1185. 
1186. 
1187. #ifdef ALTARS
1188. static void
1189. mkaltar(croom)
1190. register struct mkroom *croom;
1191. {
1192. 	register xchar mx,my;
1193. 	register int tryct = 0;
1194. 
1195. 	if(croom->rtype != OROOM) return;
1196. 
1197. 	do {
1198. 	    if(++tryct > 200) return;
1199. 	    mx = somex(croom);
1200. 	    my = somey(croom);
1201. 	} while(occupied(mx, my) || bydoor(mx, my));
1202. 
1203. 	/* Put an altar at mx, my */
1204. 	levl[mx][my].typ = ALTAR;
1205. 	levl[mx][my].scrsym = ALTAR_SYM;
1206. 	/* 0 - A_CHAOS, 1 - A_NEUTRAL, 2 - A_LAW */
1207. 	levl[mx][my].altarmask = rn2((int)A_LAW+1);
1208. }
1209. #endif /* ALTARS /**/