Fandom

Wikihack

Source:SLASH'EM 0.0.7E7F2/mklev.c

2,034pages on
this wiki
Add New Page
Talk0

Below is the full text to mklev.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mklev.c#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)mklev.c	3.4	2001/11/29	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    /* #define DEBUG */	/* uncomment to enable code debugging */
7.    
8.    #ifdef DEBUG
9.    # ifdef WIZARD
10.   #define debugpline	if (wizard) pline
11.   # else
12.   #define debugpline	pline
13.   # endif
14.   #endif
15.   
16.   /* for UNIX, Rand #def'd to (long)lrand48() or (long)random() */
17.   /* croom->lx etc are schar (width <= int), so % arith ensures that */
18.   /* conversion of result to int is reasonable */
19.   
20.   
21.   STATIC_DCL void FDECL(mkfount,(int,struct mkroom *));
22.   #ifdef SINKS
23.   STATIC_DCL void FDECL(mksink,(struct mkroom *));
24.   STATIC_DCL void FDECL(mktoilet,(struct mkroom *));
25.   #endif
26.   STATIC_DCL void FDECL(mkaltar,(struct mkroom *));
27.   STATIC_DCL void FDECL(mkgrave,(struct mkroom *));
28.   STATIC_DCL void NDECL(makevtele);
29.   STATIC_DCL void NDECL(clear_level_structures);
30.   STATIC_DCL void NDECL(makelevel);
31.   STATIC_DCL void NDECL(mineralize);
32.   STATIC_DCL boolean FDECL(bydoor,(XCHAR_P,XCHAR_P));
33.   STATIC_DCL struct mkroom *FDECL(find_branch_room, (coord *));
34.   STATIC_DCL struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P));
35.   STATIC_DCL boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*));
36.   STATIC_DCL void FDECL(makeniche,(int));
37.   STATIC_DCL void NDECL(make_niches);
38.   
39.   STATIC_PTR int FDECL( CFDECLSPEC do_comp,(const genericptr,const genericptr));
40.   
41.   STATIC_DCL void FDECL(dosdoor,(XCHAR_P,XCHAR_P,struct mkroom *,int));
42.   STATIC_DCL void FDECL(join,(int,int,BOOLEAN_P));
43.   STATIC_DCL void FDECL(do_room_or_subroom, (struct mkroom *,int,int,int,int,
44.   				       BOOLEAN_P,SCHAR_P,BOOLEAN_P,BOOLEAN_P));
45.   STATIC_DCL void NDECL(makerooms);
46.   STATIC_DCL void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P));
47.   STATIC_DCL void FDECL(mkinvpos, (XCHAR_P,XCHAR_P,int));
48.   STATIC_DCL void FDECL(mk_knox_portal, (XCHAR_P,XCHAR_P));
49.   
50.   #define create_vault()	create_room(-1, -1, 2, 2, -1, -1, VAULT, TRUE)
51.   #define init_vault()	vault_x = -1
52.   #define do_vault()	(vault_x != -1)
53.   static xchar		vault_x, vault_y;
54.   boolean goldseen;
55.   static boolean made_branch;	/* used only during level creation */
56.   
57.   /* Args must be (const genericptr) so that qsort will always be happy. */
58.   
59.   STATIC_PTR int CFDECLSPEC
60.   do_comp(vx,vy)
61.   const genericptr vx;
62.   const genericptr vy;
63.   {
64.   #ifdef LINT
65.   /* lint complains about possible pointer alignment problems, but we know
66.      that vx and vy are always properly aligned. Hence, the following
67.      bogus definition:
68.   */
69.   	return (vx == vy) ? 0 : -1;
70.   #else
71.   	register const struct mkroom *x, *y;
72.   
73.   	x = (const struct mkroom *)vx;
74.   	y = (const struct mkroom *)vy;
75.   	if(x->lx < y->lx) return(-1);
76.   	return(x->lx > y->lx);
77.   #endif /* LINT */
78.   }
79.   
80.   STATIC_OVL void
81.   finddpos(cc, xl,yl,xh,yh)
82.   coord *cc;
83.   xchar xl,yl,xh,yh;
84.   {
85.   	register xchar x, y;
86.   
87.   	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
88.   	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
89.   	if(okdoor(x, y))
90.   		goto gotit;
91.   
92.   	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
93.   		if(okdoor(x, y))
94.   			goto gotit;
95.   
96.   	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
97.   		if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
98.   			goto gotit;
99.   	/* cannot find something reasonable -- strange */
100.  	x = xl;
101.  	y = yh;
102.  gotit:
103.  	cc->x = x;
104.  	cc->y = y;
105.  	return;
106.  }
107.  
108.  void
109.  sort_rooms()
110.  {
111.  #if defined(SYSV) || defined(DGUX)
112.  	qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), do_comp);
113.  #else
114.  	qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), do_comp);
115.  #endif
116.  }
117.  
118.  STATIC_OVL void
119.  do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room)
120.      register struct mkroom *croom;
121.      int lowx, lowy;
122.      register int hix, hiy;
123.      boolean lit;
124.      schar rtype;
125.      boolean special;
126.      boolean is_room;
127.  {
128.  	register int x, y;
129.  	struct rm *lev;
130.  
131.  	/* locations might bump level edges in wall-less rooms */
132.  	/* add/subtract 1 to allow for edge locations */
133.  	if(!lowx) lowx++;
134.  	if(!lowy) lowy++;
135.  	if(hix >= COLNO-1) hix = COLNO-2;
136.  	if(hiy >= ROWNO-1) hiy = ROWNO-2;
137.  
138.  	if(lit) {
139.  		for(x = lowx-1; x <= hix+1; x++) {
140.  			lev = &levl[x][max(lowy-1,0)];
141.  			for(y = lowy-1; y <= hiy+1; y++)
142.  				lev++->lit = 1;
143.  		}
144.  		croom->rlit = 1;
145.  	} else
146.  		croom->rlit = 0;
147.  
148.  	croom->lx = lowx;
149.  	croom->hx = hix;
150.  	croom->ly = lowy;
151.  	croom->hy = hiy;
152.  	croom->rtype = rtype;
153.  	croom->doorct = 0;
154.  	/* if we're not making a vault, doorindex will still be 0
155.  	 * if we are, we'll have problems adding niches to the previous room
156.  	 * unless fdoor is at least doorindex
157.  	 */
158.  	croom->fdoor = doorindex;
159.  	croom->irregular = FALSE;
160.  
161.  	croom->nsubrooms = 0;
162.  	croom->sbrooms[0] = (struct mkroom *) 0;
163.  	if (!special) {
164.  	    for(x = lowx-1; x <= hix+1; x++)
165.  		for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
166.  		    levl[x][y].typ = HWALL;
167.  		    levl[x][y].horizontal = 1;	/* For open/secret doors. */
168.  		}
169.  	    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
170.  		for(y = lowy; y <= hiy; y++) {
171.  		    levl[x][y].typ = VWALL;
172.  		    levl[x][y].horizontal = 0;	/* For open/secret doors. */
173.  		}
174.  	    for(x = lowx; x <= hix; x++) {
175.  		lev = &levl[x][lowy];
176.  		for(y = lowy; y <= hiy; y++)
177.  		    lev++->typ = ROOM;
178.  	    }
179.  	    if (is_room) {
180.  		levl[lowx-1][lowy-1].typ = TLCORNER;
181.  		levl[hix+1][lowy-1].typ = TRCORNER;
182.  		levl[lowx-1][hiy+1].typ = BLCORNER;
183.  		levl[hix+1][hiy+1].typ = BRCORNER;
184.  	    } else {	/* a subroom */
185.  		wallification(lowx-1, lowy-1, hix+1, hiy+1, FALSE);
186.  	    }
187.  	}
188.  }
189.  
190.  
191.  void
192.  add_room(lowx, lowy, hix, hiy, lit, rtype, special)
193.  register int lowx, lowy, hix, hiy;
194.  boolean lit;
195.  schar rtype;
196.  boolean special;
197.  {
198.  	register struct mkroom *croom;
199.  
200.  	croom = &rooms[nroom];
201.  	do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,
202.  					    rtype, special, (boolean) TRUE);
203.  	croom++;
204.  	croom->hx = -1;
205.  	nroom++;
206.  }
207.  
208.  void
209.  add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special)
210.  struct mkroom *proom;
211.  register int lowx, lowy, hix, hiy;
212.  boolean lit;
213.  schar rtype;
214.  boolean special;
215.  {
216.  	register struct mkroom *croom;
217.  
218.  	croom = &subrooms[nsubroom];
219.  	do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,
220.  					    rtype, special, (boolean) FALSE);
221.  	proom->sbrooms[proom->nsubrooms++] = croom;
222.  	croom++;
223.  	croom->hx = -1;
224.  	nsubroom++;
225.  }
226.  
227.  STATIC_OVL void
228.  makerooms()
229.  {
230.  	boolean tried_vault = FALSE;
231.  
232.  	/* make rooms until satisfied */
233.  	/* rnd_rect() will returns 0 if no more rects are available... */
234.  	while(nroom < MAXNROFROOMS && rnd_rect()) {
235.  		if(nroom >= (MAXNROFROOMS/6) && rn2(2) && !tried_vault) {
236.  			tried_vault = TRUE;
237.  			if (create_vault()) {
238.  				vault_x = rooms[nroom].lx;
239.  				vault_y = rooms[nroom].ly;
240.  				rooms[nroom].hx = -1;
241.  			}
242.  		} else
243.  		    if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
244.  			return;
245.  	}
246.  	return;
247.  }
248.  
249.  STATIC_OVL void
250.  join(a,b,nxcor)
251.  register int a, b;
252.  boolean nxcor;
253.  {
254.  	coord cc,tt, org, dest;
255.  	register xchar tx, ty, xx, yy;
256.  	register struct mkroom *croom, *troom;
257.  	register int dx, dy;
258.  
259.  	croom = &rooms[a];
260.  	troom = &rooms[b];
261.  
262.  	/* find positions cc and tt for doors in croom and troom
263.  	   and direction for a corridor between them */
264.  
265.  	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
266.  	if(troom->lx > croom->hx) {
267.  		dx = 1;
268.  		dy = 0;
269.  		xx = croom->hx+1;
270.  		tx = troom->lx-1;
271.  		finddpos(&cc, xx, croom->ly, xx, croom->hy);
272.  		finddpos(&tt, tx, troom->ly, tx, troom->hy);
273.  	} else if(troom->hy < croom->ly) {
274.  		dy = -1;
275.  		dx = 0;
276.  		yy = croom->ly-1;
277.  		finddpos(&cc, croom->lx, yy, croom->hx, yy);
278.  		ty = troom->hy+1;
279.  		finddpos(&tt, troom->lx, ty, troom->hx, ty);
280.  	} else if(troom->hx < croom->lx) {
281.  		dx = -1;
282.  		dy = 0;
283.  		xx = croom->lx-1;
284.  		tx = troom->hx+1;
285.  		finddpos(&cc, xx, croom->ly, xx, croom->hy);
286.  		finddpos(&tt, tx, troom->ly, tx, troom->hy);
287.  	} else {
288.  		dy = 1;
289.  		dx = 0;
290.  		yy = croom->hy+1;
291.  		ty = troom->ly-1;
292.  		finddpos(&cc, croom->lx, yy, croom->hx, yy);
293.  		finddpos(&tt, troom->lx, ty, troom->hx, ty);
294.  	}
295.  	xx = cc.x;
296.  	yy = cc.y;
297.  	tx = tt.x - dx;
298.  	ty = tt.y - dy;
299.  	if(nxcor && levl[xx+dx][yy+dy].typ)
300.  		return;
301.  	if (okdoor(xx,yy) || !nxcor)
302.  	    dodoor(xx,yy,croom);
303.  
304.  	org.x  = xx+dx; org.y  = yy+dy;
305.  	dest.x = tx; dest.y = ty;
306.  
307.  	/* KMH -- Support for arboreal levels */
308.  	if (!dig_corridor(&org, &dest, nxcor,
309.  			level.flags.arboreal ? ROOM : CORR, STONE))
310.  	    return;
311.  
312.  	/* we succeeded in digging the corridor */
313.  	if (okdoor(tt.x, tt.y) || !nxcor)
314.  	    dodoor(tt.x, tt.y, troom);
315.  
316.  	if(smeq[a] < smeq[b])
317.  		smeq[b] = smeq[a];
318.  	else
319.  		smeq[a] = smeq[b];
320.  }
321.  
322.  void
323.  makecorridors()
324.  {
325.  	int a, b, i;
326.  	boolean any = TRUE;
327.  
328.  	for(a = 0; a < nroom-1; a++) {
329.  		join(a, a+1, FALSE);
330.  		if(!rn2(50)) break; /* allow some randomness */
331.  	}
332.  	for(a = 0; a < nroom-2; a++)
333.  	    if(smeq[a] != smeq[a+2])
334.  		join(a, a+2, FALSE);
335.  	for(a = 0; any && a < nroom; a++) {
336.  	    any = FALSE;
337.  	    for(b = 0; b < nroom; b++)
338.  		if(smeq[a] != smeq[b]) {
339.  		    join(a, b, FALSE);
340.  		    any = TRUE;
341.  		}
342.  	}
343.  	if(nroom > 2)
344.  	    for(i = rn2(nroom) + 4; i; i--) {
345.  		a = rn2(nroom);
346.  		b = rn2(nroom-2);
347.  		if(b >= a) b += 2;
348.  		join(a, b, TRUE);
349.  	    }
350.  }
351.  
352.  /* ALI - Artifact doors: Track doors in maze levels as well */
353.  
354.  int
355.  add_door(x,y,aroom)
356.  register int x, y;
357.  register struct mkroom *aroom;
358.  {
359.  	register struct mkroom *broom;
360.  	register int tmp;
361.  
362.  	if (doorindex == DOORMAX)
363.  	    return -1;
364.  
365.  	if (aroom) {
366.  	    aroom->doorct++;
367.  	    broom = aroom+1;
368.  	} else
369.  	    /* ALI
370.  	     * Roomless doors must go right at the beginning of the list
371.  	     */
372.  	    broom = &rooms[0];
373.  	if(broom->hx < 0)
374.  	    tmp = doorindex;
375.  	else
376.  	    for(tmp = doorindex; tmp > broom->fdoor; tmp--)
377.  		doors[tmp] = doors[tmp-1];
378.  	doorindex++;
379.  	doors[tmp].x = x;
380.  	doors[tmp].y = y;
381.  	for( ; broom->hx >= 0; broom++) broom->fdoor++;
382.  	doors[tmp].arti_key = 0;
383.  	return tmp;
384.  }
385.  
386.  STATIC_OVL void
387.  dosdoor(x,y,aroom,type)
388.  register xchar x, y;
389.  register struct mkroom *aroom;
390.  register int type;
391.  {
392.  	boolean shdoor = ((*in_rooms(x, y, SHOPBASE))? TRUE : FALSE);
393.  
394.  	if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */
395.  		type = DOOR;
396.  	levl[x][y].typ = type;
397.  	if(type == DOOR) {
398.  	    if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */
399.  		if(!rn2(5))
400.  		    levl[x][y].doormask = D_ISOPEN;
401.  		else if(!rn2(6))
402.  		    levl[x][y].doormask = D_LOCKED;
403.  		else
404.  		    levl[x][y].doormask = D_CLOSED;
405.  
406.  		if (levl[x][y].doormask != D_ISOPEN && !shdoor &&
407.  		    level_difficulty() >= 5 && !rn2(25))
408.  		    levl[x][y].doormask |= D_TRAPPED;
409.  	    } else
410.  #ifdef STUPID
411.  		if (shdoor)
412.  			levl[x][y].doormask = D_ISOPEN;
413.  		else
414.  			levl[x][y].doormask = D_NODOOR;
415.  #else
416.  		levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
417.  #endif
418.  	    if(levl[x][y].doormask & D_TRAPPED) {
419.  		struct monst *mtmp;
420.  
421.  		if (level_difficulty() >= 9 && !rn2(5) &&
422.  		   !((mvitals[PM_SMALL_MIMIC].mvflags & G_GONE) &&
423.  		     (mvitals[PM_LARGE_MIMIC].mvflags & G_GONE) &&
424.  		     (mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) {
425.  		    /* make a mimic instead */
426.  		    levl[x][y].doormask = D_NODOOR;
427.  		    mtmp = makemon(mkclass(S_MIMIC,0), x, y, NO_MM_FLAGS);
428.  		    if (mtmp)
429.  			set_mimic_sym(mtmp);
430.  		}
431.  	    }
432.  	    /* newsym(x,y); */
433.  	} else { /* SDOOR */
434.  		if(shdoor || !rn2(5))	levl[x][y].doormask = D_LOCKED;
435.  		else			levl[x][y].doormask = D_CLOSED;
436.  
437.  		if(!shdoor && level_difficulty() >= 4 && !rn2(20))
438.  		    levl[x][y].doormask |= D_TRAPPED;
439.  	}
440.  
441.  	add_door(x,y,aroom);
442.  }
443.  
444.  STATIC_OVL boolean
445.  place_niche(aroom,dy,xx,yy)
446.  register struct mkroom *aroom;
447.  int *dy, *xx, *yy;
448.  {
449.  	coord dd;
450.  
451.  	if(rn2(2)) {
452.  	    *dy = 1;
453.  	    finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
454.  	} else {
455.  	    *dy = -1;
456.  	    finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
457.  	}
458.  	*xx = dd.x;
459.  	*yy = dd.y;
460.  	return((boolean)((isok(*xx,*yy+*dy) && levl[*xx][*yy+*dy].typ == STONE)
461.  	    && (isok(*xx,*yy-*dy) && !IS_POOL(levl[*xx][*yy-*dy].typ)
462.  				  && !IS_FURNITURE(levl[*xx][*yy-*dy].typ))));
463.  }
464.  
465.  /* there should be one of these per trap, in the same order as trap.h */
466.  static NEARDATA const char *trap_engravings[TRAPNUM] = {
467.  			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
468.  			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
469.  			(char *)0, (char *)0, (char *)0, (char *)0,
470.  			/* 14..16: trap door, teleport, level-teleport */
471.  			"Vlad was here", "ad aerarium", "ad aerarium",
472.  			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
473.  			(char *)0,
474.  };
475.  
476.  STATIC_OVL void
477.  makeniche(trap_type)
478.  int trap_type;
479.  {
480.  	register struct mkroom *aroom;
481.  	register struct rm *rm;
482.  	register int vct = 8;
483.  	int dy, xx, yy;
484.  	register struct trap *ttmp;
485.  
486.  	if(doorindex < DOORMAX)
487.  	  while(vct--) {
488.  	    aroom = &rooms[rn2(nroom)];
489.  	    if(aroom->rtype != OROOM) continue;	/* not an ordinary room */
490.  	    if(aroom->doorct == 1 && rn2(5)) continue;
491.  	    if(!place_niche(aroom,&dy,&xx,&yy)) continue;
492.  
493.  	    rm = &levl[xx][yy+dy];
494.  	    if(trap_type || !rn2(4)) {
495.  
496.  		rm->typ = SCORR;
497.  		if(trap_type) {
498.  		    if((trap_type == HOLE || trap_type == TRAPDOOR)
499.  			&& !Can_fall_thru(&u.uz))
500.  			trap_type = ROCKTRAP;
501.  		    ttmp = maketrap(xx, yy+dy, trap_type);
502.  		    if (ttmp) {
503.  			if (trap_type != ROCKTRAP) ttmp->once = 1;
504.  			if (trap_engravings[trap_type]) {
505.  			    make_engr_at(xx, yy-dy,
506.  				     trap_engravings[trap_type], 0L, DUST);
507.  			    wipe_engr_at(xx, yy-dy, 5); /* age it a little */
508.  			}
509.  		    }
510.  		}
511.  		dosdoor(xx, yy, aroom, SDOOR);
512.  	    } else {
513.  		rm->typ = CORR;
514.  		if(rn2(7))
515.  		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
516.  		else {
517.  		    if (!level.flags.noteleport)
518.  			(void) mksobj_at(SCR_TELEPORTATION,
519.  					 xx, yy+dy, TRUE, FALSE);
520.  		    if (!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE);
521.  		}
522.  	    }
523.  	    return;
524.  	}
525.  }
526.  
527.  STATIC_OVL void
528.  make_niches()
529.  {
530.  	register int ct = rnd((nroom>>1) + 1), dep = depth(&u.uz);
531.  
532.  	boolean	ltptr = (!level.flags.noteleport && dep > 15),
533.  		vamp = (dep > 5 && dep < 25);
534.  
535.  	while(ct--) {
536.  		if (ltptr && !rn2(6)) {
537.  			ltptr = FALSE;
538.  			makeniche(LEVEL_TELEP);
539.  		} else if (vamp && !rn2(6)) {
540.  			vamp = FALSE;
541.  			makeniche(TRAPDOOR);
542.  		} else	makeniche(NO_TRAP);
543.  	}
544.  }
545.  
546.  STATIC_OVL void
547.  makevtele()
548.  {
549.  	makeniche(TELEP_TRAP);
550.  }
551.  
552.  /* clear out various globals that keep information on the current level.
553.   * some of this is only necessary for some types of levels (maze, normal,
554.   * special) but it's easier to put it all in one place than make sure
555.   * each type initializes what it needs to separately.
556.   */
557.  STATIC_OVL void
558.  clear_level_structures()
559.  {
560.  #ifdef DISPLAY_LAYERS
561.  	static struct rm zerorm = { S_stone, 0, 0, 0, 0, 0,
562.  #else
563.  	static struct rm zerorm = { cmap_to_glyph(S_stone),
564.  #endif
565.  						0, 0, 0, 0, 0, 0, 0, 0 };
566.  	register int x,y;
567.  	register struct rm *lev;
568.  
569.  	for(x=0; x<COLNO; x++) {
570.  	    lev = &levl[x][0];
571.  	    for(y=0; y<ROWNO; y++) {
572.  		*lev++ = zerorm;
573.  #ifdef MICROPORT_BUG
574.  		level.objects[x][y] = (struct obj *)0;
575.  		level.monsters[x][y] = (struct monst *)0;
576.  #endif
577.  	    }
578.  	}
579.  #ifndef MICROPORT_BUG
580.  	(void) memset((genericptr_t)level.objects, 0, sizeof(level.objects));
581.  	(void) memset((genericptr_t)level.monsters, 0, sizeof(level.monsters));
582.  #endif
583.  	level.objlist = (struct obj *)0;
584.  	level.buriedobjlist = (struct obj *)0;
585.  	level.monlist = (struct monst *)0;
586.  	level.damagelist = (struct damage *)0;
587.  
588.  	level.flags.nfountains = 0;
589.  	level.flags.nsinks = 0;
590.  	level.flags.has_shop = 0;
591.  	level.flags.has_vault = 0;
592.  	level.flags.has_zoo = 0;
593.  	level.flags.has_court = 0;
594.  	level.flags.has_morgue = level.flags.graveyard = 0;
595.  	level.flags.has_beehive = 0;
596.  	level.flags.has_barracks = 0;
597.  	level.flags.has_lemurepit = 0;
598.  	level.flags.has_migohive = 0;
599.  	level.flags.has_fungusfarm = 0;
600.  	level.flags.has_temple = 0;
601.  	level.flags.has_swamp = 0;
602.  	level.flags.noteleport = 0;
603.  	level.flags.hardfloor = 0;
604.  	level.flags.nommap = 0;
605.  	level.flags.hero_memory = 1;
606.  	level.flags.shortsighted = 0;
607.  	level.flags.arboreal = 0;
608.  	level.flags.is_maze_lev = 0;
609.  	level.flags.is_cavernous_lev = 0;
610.  	/* KMH -- more level properties */
611.  	level.flags.arboreal = 0;
612.  
613.  	/* [DS] - Michael Clarke's Lethe flag */
614.  	level.flags.lethe = 0;
615.  
616.  	nroom = 0;
617.  	rooms[0].hx = -1;
618.  	nsubroom = 0;
619.  	subrooms[0].hx = -1;
620.  	doorindex = 0;
621.  	init_rect();
622.  	init_vault();
623.  	xdnstair = ydnstair = xupstair = yupstair = 0;
624.  	sstairs.sx = sstairs.sy = 0;
625.  	xdnladder = ydnladder = xupladder = yupladder = 0;
626.  	made_branch = FALSE;
627.  	clear_regions();
628.  }
629.  
630.  STATIC_OVL void
631.  makelevel()
632.  {
633.  	register struct mkroom *croom, *troom;
634.  	register int tryct;
635.  	register int x, y;
636.  	struct monst *tmonst;	/* always put a web with a spider */
637.  	branch *branchp;
638.  	int room_threshold;
639.  
640.  	if(wiz1_level.dlevel == 0) init_dungeons();
641.  	oinit();	/* assign level dependent obj probabilities */
642.  	clear_level_structures();
643.  
644.  	{
645.  	    register s_level *slev = Is_special(&u.uz);
646.  
647.  	    /* check for special levels */
648.  #ifdef REINCARNATION
649.  	    if (slev && !Is_rogue_level(&u.uz))
650.  #else
651.  	    if (slev)
652.  #endif
653.  	    {
654.  		    makemaz(slev->proto);
655.  		    return;
656.  	    } else if (dungeons[u.uz.dnum].proto[0]) {
657.  		    makemaz("");
658.  		    return;
659.  	    } else if (In_mines(&u.uz)) {
660.  		    makemaz("minefill");
661.  		    return;
662.  	    } else if (In_quest(&u.uz)) {
663.  		    char        fillname[16];
664.  		    s_level	*loc_lev;
665.  
666.  		    Sprintf(fillname, "%s-loca", urole.filecode);
667.  		    loc_lev = find_level(fillname);
668.  
669.  		    Sprintf(fillname, "%s-fil", urole.filecode);
670.  		    Strcat(fillname,
671.  			   (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
672.  		    makemaz(fillname);
673.  		    return;
674.  	    } else if(In_hell(&u.uz) ||
675.  		  (rn2(5) && u.uz.dnum == medusa_level.dnum
676.  			  && depth(&u.uz) > depth(&medusa_level))) {
677.  		    makemaz("");
678.  		    return;
679.  	    }
680.  	}
681.  
682.  	/* otherwise, fall through - it's a "regular" level. */
683.  
684.  #ifdef REINCARNATION
685.  	if (Is_rogue_level(&u.uz)) {
686.  		makeroguerooms();
687.  		makerogueghost();
688.  	} else
689.  #endif
690.  		makerooms();
691.  	sort_rooms();
692.  
693.  	/* construct stairs (up and down in different rooms if possible) */
694.  	croom = &rooms[rn2(nroom)];
695.  	if (!Is_botlevel(&u.uz))
696.  	     mkstairs(somex(croom), somey(croom), 0, croom);	/* down */
697.  	if (nroom > 1) {
698.  	    troom = croom;
699.  	    croom = &rooms[rn2(nroom-1)];
700.  	    if (croom == troom) croom++;
701.  	}
702.  
703.  	if (u.uz.dlevel != 1) {
704.  	    xchar sx, sy;
705.  	    do {
706.  		sx = somex(croom);
707.  		sy = somey(croom);
708.  	    } while(occupied(sx, sy));
709.  	    mkstairs(sx, sy, 1, croom);	/* up */
710.  	}
711.  
712.  	branchp = Is_branchlev(&u.uz);	/* possible dungeon branch */
713.  	room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed
714.  					     to allow a random special room */
715.  #ifdef REINCARNATION
716.  	if (Is_rogue_level(&u.uz)) goto skip0;
717.  #endif
718.  	makecorridors();
719.  	make_niches();
720.  
721.  	/* make a secret treasure vault, not connected to the rest */
722.  	if(do_vault()) {
723.  		xchar w,h;
724.  #ifdef DEBUG
725.  		debugpline("trying to make a vault...");
726.  #endif
727.  		w = 1;
728.  		h = 1;
729.  		if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) {
730.  		    fill_vault:
731.  			add_room(vault_x, vault_y, vault_x+w,
732.  				 vault_y+h, TRUE, VAULT, FALSE);
733.  			level.flags.has_vault = 1;
734.  			++room_threshold;
735.  			fill_room(&rooms[nroom - 1], FALSE);
736.  			mk_knox_portal(vault_x+w, vault_y+h);
737.  			if(!level.flags.noteleport && !rn2(3)) makevtele();
738.  		} else if(rnd_rect() && create_vault()) {
739.  			vault_x = rooms[nroom].lx;
740.  			vault_y = rooms[nroom].ly;
741.  			if (check_room(&vault_x, &w, &vault_y, &h, TRUE))
742.  				goto fill_vault;
743.  			else
744.  				rooms[nroom].hx = -1;
745.  		}
746.  	}
747.  
748.      {
749.  	register int u_depth = depth(&u.uz);
750.  
751.  #ifdef WIZARD
752.  	if(wizard && nh_getenv("SHOPTYPE")) mkroom(SHOPBASE); else
753.  #endif
754.  	if (u_depth > 1 &&
755.  	    u_depth < depth(&medusa_level) &&
756.  	    nroom >= room_threshold &&
757.  	    rn2(u_depth) < 3) mkroom(SHOPBASE);
758.   
759.  	/* [Tom] totally reorganized this into categories... used
760.  	   to be only one special room on a level... now allows
761.  	   one of each major type */
762.  	else {
763.  	    /* courtrooms & barracks */
764.  	    if(depth(&u.uz) > 4 && !rn2(12)) mkroom(COURT);
765.  	else if (u_depth > 5 && !rn2(8) &&
766.  	   !(mvitals[PM_LEPRECHAUN].mvflags & G_GONE)) mkroom(LEPREHALL);
767.  	    else if(depth(&u.uz) > 14 && !rn2(12)) mkroom(GIANTCOURT);
768.  	    else if(depth(&u.uz) > 14 && !rn2(7) &&
769.  		(mvitals[PM_SOLDIER].mvflags & G_GONE)) mkroom(BARRACKS);
770.  	
771.  	    /* hives */
772.  	    if(depth(&u.uz) > 9 && !rn2(12) &&
773.  		(mvitals[PM_KILLER_BEE].mvflags & G_GONE)) mkroom(BEEHIVE);
774.  	else if (u_depth > 12 && !rn2(8)) mkroom(ANTHOLE);
775.  
776.  	    /* zoos */
777.  	    if(depth(&u.uz) > 6 && !rn2(12)) mkroom(ZOO);
778.  	    /* fungus farms are rare... */
779.  	    else if (u_depth > 7 && !rn2(25)) mkroom(FUNGUSFARM);
780.  	    else if(depth(&u.uz) > 9 && !rn2(15)) mkroom(REALZOO);
781.  
782.  	    /* neat rooms */
783.  	    if(depth(&u.uz) > 8 && !rn2(13)) mkroom(TEMPLE);
784.  	    else if(depth(&u.uz) > 11 && !rn2(14)) mkroom(MORGUE);
785.  	    else if(depth(&u.uz) > 13 && !rn2(15)) mkroom(BADFOODSHOP);
786.  	    else if(depth(&u.uz) > 18 && !rn2(7)) mkroom(SWAMP);
787.  
788.  	    /* dangerous ones */
789.  	    if (u_depth > 16 && !rn2(8) &&
790.  	   !(mvitals[PM_COCKATRICE].mvflags & G_GONE)) mkroom(COCKNEST);
791.  	    else if(depth(&u.uz) > 20 && !rn2(20)) mkroom(DRAGONLAIR);
792.  	    else if (u_depth > 25 && !rn2(20) && 
793.  		!(mvitals[PM_MIGO_DRONE].mvflags & G_GONE)) mkroom(MIGOHIVE);
794.  	    /* [DS] the restriction of lemure pits to Gehennom means they're
795.  	     *      never going to show up randomly (no random room+corridor
796.  	     *      levels in Gehennom). Perhaps this should be removed? */
797.  	    else if (In_hell(&u.uz) && !rn2(12) &&
798.  		!(mvitals[PM_LEMURE].mvflags & G_GONE)) mkroom(LEMUREPIT);
799.      }
800.  
801.  #ifdef REINCARNATION
802.  skip0:
803.  #endif
804.  	/* Place multi-dungeon branch. */
805.  	place_branch(branchp, 0, 0);
806.  
807.  	/* for each room: put things inside */
808.  	for(croom = rooms; croom->hx > 0; croom++) {
809.  		if(croom->rtype != OROOM) continue;
810.  
811.  		/* put a sleeping monster inside */
812.  		/* Note: monster may be on the stairs. This cannot be
813.  		   avoided: maybe the player fell through a trap door
814.  		   while a monster was on the stairs. Conclusion:
815.  		   we have to check for monsters on the stairs anyway. */
816.  		if(u.uhave.amulet || !rn2(3)) {
817.  		    x = somex(croom); y = somey(croom);
818.  		    tmonst = makemon((struct permonst *) 0, x,y,NO_MM_FLAGS);
819.  		    if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] &&
820.  			    !occupied(x, y))
821.  			(void) maketrap(x, y, WEB);
822.  		}
823.  		/* put traps and mimics inside */
824.  		goldseen = FALSE;
825.  		x = 8 - (level_difficulty()/6);
826.  		if (x <= 1) x = 2;
827.  		while (!rn2(x))
828.  		    mktrap(0,0,croom,(coord*)0);
829.  		if (!goldseen && !rn2(3))
830.  		    (void) mkgold(0L, somex(croom), somey(croom));
831.  #ifdef REINCARNATION
832.  		x = 80 - (depth(&u.uz) * 2);
833.  		if (x < 2) x = 2;
834.  		if(!rn2(x)) mkgrave(croom);
835.  
836.  		if(Is_rogue_level(&u.uz)) goto skip_nonrogue;
837.  #endif
838.  		if(!rn2(10)) mkfount(0,croom);
839.  #ifdef SINKS
840.  		if(!rn2(60)) {
841.  		    mksink(croom);
842.  		    if(!rn2(3)) mktoilet(croom);
843.  		}
844.  #endif
845.  		x = 80 - (depth(&u.uz) * 2);
846.  		if (x < 2) x = 2;
847.  		if(!rn2(x)) mkgrave(croom);
848.  		if(!rn2(60)) mkaltar(croom);
849.  
850.  		/* put statues inside */
851.  		if(!rn2(20))
852.  		    (void) mkcorpstat(STATUE, (struct monst *)0,
853.  				      (struct permonst *)0,
854.  				      somex(croom), somey(croom), TRUE);
855.  		/* put box/chest inside;
856.  		 *  40% chance for at least 1 box, regardless of number
857.  		 *  of rooms; about 5 - 7.5% for 2 boxes, least likely
858.  		 *  when few rooms; chance for 3 or more is neglible.
859.  		 */
860.  		if(!rn2(nroom * 5 / 2))
861.  		    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
862.  				     somex(croom), somey(croom), TRUE, FALSE);
863.  
864.  		/* maybe make some graffiti */
865.  		if(!rn2(27 + 3 * abs(depth(&u.uz)))) {
866.  		    char buf[BUFSZ];
867.  		    const char *mesg = random_engraving(buf);
868.  		    if (mesg) {
869.  			do {
870.  			    x = somex(croom);  y = somey(croom);
871.  			} while(levl[x][y].typ != ROOM && !rn2(40));
872.  			if (!(IS_POOL(levl[x][y].typ) ||
873.  			      IS_FURNITURE(levl[x][y].typ)))
874.  			    make_engr_at(x, y, mesg, 0L, MARK);
875.  		    }
876.  		}
877.  
878.  #ifdef REINCARNATION
879.  	skip_nonrogue:
880.  #endif
881.  
882.  /* STEPHEN WHITE'S NEW CODE */
883.  		if(!rn2(5)) {
884.  		    (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
885.  		    tryct = 0;
886.  		    while(!rn2(4)) {
887.  			if(++tryct > 100) {
888.  			    impossible("tryct overflow4");
889.  			    break;
890.  			}
891.  			(void) mkobj_at(0, somex(croom), somey(croom), TRUE);
892.  		    }
893.  		}
894.  	}
895.     }
896.  }
897.  
898.  /*
899.   *	Place deposits of minerals (gold and misc gems) in the stone
900.   *	surrounding the rooms on the map.
901.   *	Also place kelp in water.
902.   */
903.  
904.  STATIC_OVL void
905.  mineralize()
906.  {
907.  	s_level *sp;
908.  	struct obj *otmp;
909.  	int goldprob, gemprob, x, y, cnt;
910.  
911.  
912.  	/* Place kelp, except on the plane of water */
913.  	if (In_endgame(&u.uz)) return;
914.  	for (x = 2; x < (COLNO - 2); x++)
915.  	    for (y = 1; y < (ROWNO - 1); y++)
916.  		if ((levl[x][y].typ == POOL && !rn2(10)) ||
917.  			(levl[x][y].typ == MOAT && !rn2(30)))
918.  	    	    (void)mksobj_at(KELP_FROND, x, y, TRUE, FALSE);
919.  
920.  	/* determine if it is even allowed;
921.  	   almost all special levels are excluded */
922.  	if (In_hell(&u.uz) || In_V_tower(&u.uz) ||
923.  #ifdef REINCARNATION
924.  		Is_rogue_level(&u.uz) ||
925.  #endif
926.  		level.flags.arboreal ||
927.  		((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz)
928.  					&& (!In_mines(&u.uz) || sp->flags.town)
929.  	    )) return;
930.  
931.  	/* basic level-related probabilities */
932.  	goldprob = 20 + depth(&u.uz) / 3;
933.  	gemprob = goldprob / 4;
934.  
935.  	/* mines have ***MORE*** goodies - otherwise why mine? */
936.  	if (In_mines(&u.uz)) {
937.  	    goldprob *= 2;
938.  	    gemprob *= 3;
939.  	} else if (In_quest(&u.uz)) {
940.  	    goldprob /= 4;
941.  	    gemprob /= 6;
942.  	}
943.  
944.  	/*
945.  	 * Seed rock areas with gold and/or gems.
946.  	 * We use fairly low level object handling to avoid unnecessary
947.  	 * overhead from placing things in the floor chain prior to burial.
948.  	 */
949.  	for (x = 2; x < (COLNO - 2); x++)
950.  	  for (y = 1; y < (ROWNO - 1); y++)
951.  	    if (levl[x][y+1].typ != STONE) {	 /* <x,y> spot not eligible */
952.  		y += 2;		/* next two spots aren't eligible either */
953.  	    } else if (levl[x][y].typ != STONE) { /* this spot not eligible */
954.  		y += 1;		/* next spot isn't eligible either */
955.  	    } else if (!(levl[x][y].wall_info & W_NONDIGGABLE) &&
956.  		  levl[x][y-1].typ   == STONE &&
957.  		  levl[x+1][y-1].typ == STONE && levl[x-1][y-1].typ == STONE &&
958.  		  levl[x+1][y].typ   == STONE && levl[x-1][y].typ   == STONE &&
959.  		  levl[x+1][y+1].typ == STONE && levl[x-1][y+1].typ == STONE) {
960.  		if (rn2(1000) < goldprob) {
961.  		    if ((otmp = mksobj(GOLD_PIECE, FALSE, FALSE)) != 0) {
962.  			otmp->ox = x,  otmp->oy = y;
963.  			otmp->quan = 1L + rnd(goldprob * 3);
964.  			otmp->owt = weight(otmp);
965.  			if (!rn2(3)) add_to_buried(otmp);
966.  			else place_object(otmp, x, y);
967.  		    }
968.  		}
969.  		if (rn2(1000) < gemprob) {
970.  		    for (cnt = rnd(2 + dunlev(&u.uz) / 3); cnt > 0; cnt--)
971.  			if ((otmp = mkobj(GEM_CLASS, FALSE)) != 0) {
972.  			    if (otmp->otyp == ROCK) {
973.  				dealloc_obj(otmp);	/* discard it */
974.  			    } else {
975.  				otmp->ox = x,  otmp->oy = y;
976.  				if (!rn2(3)) add_to_buried(otmp);
977.  				else place_object(otmp, x, y);
978.  			    }
979.  		    }
980.  		}
981.  	    }
982.  }
983.  
984.  void
985.  mklev()
986.  {
987.  	struct mkroom *croom;
988.  
989.  	if(getbones()) return;
990.  	in_mklev = TRUE;
991.  	makelevel();
992.  	bound_digging();
993.  	mineralize();
994.  	in_mklev = FALSE;
995.  	/* has_morgue gets cleared once morgue is entered; graveyard stays
996.  	   set (graveyard might already be set even when has_morgue is clear
997.  	   [see fixup_special()], so don't update it unconditionally) */
998.  	if (level.flags.has_morgue)
999.  	    level.flags.graveyard = 1;
1000. 	if(!level.flags.is_maze_lev) {
1001. 	    for (croom = &rooms[0]; croom != &rooms[nroom]; croom++)
1002. #ifdef SPECIALIZATION
1003. 		topologize(croom, FALSE);
1004. #else
1005. 		topologize(croom);
1006. #endif
1007. 	}
1008. 	set_wall_state();
1009. }
1010. 
1011. void
1012. #ifdef SPECIALIZATION
1013. topologize(croom, do_ordinary)
1014. register struct mkroom *croom;
1015. boolean do_ordinary;
1016. #else
1017. topologize(croom)
1018. register struct mkroom *croom;
1019. #endif
1020. {
1021. 	register int x, y, roomno = (croom - rooms) + ROOMOFFSET;
1022. 	register int lowx = croom->lx, lowy = croom->ly;
1023. 	register int hix = croom->hx, hiy = croom->hy;
1024. #ifdef SPECIALIZATION
1025. 	register schar rtype = croom->rtype;
1026. #endif
1027. 	register int subindex, nsubrooms = croom->nsubrooms;
1028. 
1029. 	/* skip the room if already done; i.e. a shop handled out of order */
1030. 	/* also skip if this is non-rectangular (it _must_ be done already) */
1031. 	if ((int) levl[lowx][lowy].roomno == roomno || croom->irregular)
1032. 	    return;
1033. #ifdef SPECIALIZATION
1034. # ifdef REINCARNATION
1035. 	if (Is_rogue_level(&u.uz))
1036. 	    do_ordinary = TRUE;		/* vision routine helper */
1037. # endif
1038. 	if ((rtype != OROOM) || do_ordinary)
1039. #endif
1040. 	{
1041. 	    /* do innards first */
1042. 	    for(x = lowx; x <= hix; x++)
1043. 		for(y = lowy; y <= hiy; y++)
1044. #ifdef SPECIALIZATION
1045. 		    if (rtype == OROOM)
1046. 			levl[x][y].roomno = NO_ROOM;
1047. 		    else
1048. #endif
1049. 			levl[x][y].roomno = roomno;
1050. 	    /* top and bottom edges */
1051. 	    for(x = lowx-1; x <= hix+1; x++)
1052. 		for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
1053. 		    levl[x][y].edge = 1;
1054. 		    if (levl[x][y].roomno)
1055. 			levl[x][y].roomno = SHARED;
1056. 		    else
1057. 			levl[x][y].roomno = roomno;
1058. 		}
1059. 	    /* sides */
1060. 	    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
1061. 		for(y = lowy; y <= hiy; y++) {
1062. 		    levl[x][y].edge = 1;
1063. 		    if (levl[x][y].roomno)
1064. 			levl[x][y].roomno = SHARED;
1065. 		    else
1066. 			levl[x][y].roomno = roomno;
1067. 		}
1068. 	}
1069. 	/* subrooms */
1070. 	for (subindex = 0; subindex < nsubrooms; subindex++)
1071. #ifdef SPECIALIZATION
1072. 		topologize(croom->sbrooms[subindex], (rtype != OROOM));
1073. #else
1074. 		topologize(croom->sbrooms[subindex]);
1075. #endif
1076. }
1077. 
1078. /* Find an unused room for a branch location. */
1079. STATIC_OVL struct mkroom *
1080. find_branch_room(mp)
1081.     coord *mp;
1082. {
1083.     struct mkroom *croom = 0;
1084. 
1085.     if (nroom == 0) {
1086. 	mazexy(mp);		/* already verifies location */
1087.     } else {
1088. 	/* not perfect - there may be only one stairway */
1089. 	if(nroom > 2) {
1090. 	    int tryct = 0;
1091. 
1092. 	    do
1093. 		croom = &rooms[rn2(nroom)];
1094. 	    while((croom == dnstairs_room || croom == upstairs_room ||
1095. 		  croom->rtype != OROOM) && (++tryct < 100));
1096. 	} else
1097. 	    croom = &rooms[rn2(nroom)];
1098. 
1099. 	do {
1100. 	    if (!somexy(croom, mp))
1101. 		impossible("Can't place branch!");
1102. 	} while(occupied(mp->x, mp->y) ||
1103. 	    (levl[mp->x][mp->y].typ != CORR && levl[mp->x][mp->y].typ != ROOM));
1104.     }
1105.     return croom;
1106. }
1107. 
1108. /* Find the room for (x,y).  Return null if not in a room. */
1109. STATIC_OVL struct mkroom *
1110. pos_to_room(x, y)
1111.     xchar x, y;
1112. {
1113.     int i;
1114.     struct mkroom *curr;
1115. 
1116.     for (curr = rooms, i = 0; i < nroom; curr++, i++)
1117. 	if (inside_room(curr, x, y)) return curr;;
1118.     return (struct mkroom *) 0;
1119. }
1120. 
1121. 
1122. /* If given a branch, randomly place a special stair or portal. */
1123. void
1124. place_branch(br, x, y)
1125. branch *br;	/* branch to place */
1126. xchar x, y;	/* location */
1127. {
1128. 	coord	      m;
1129. 	d_level	      *dest;
1130. 	boolean	      make_stairs;
1131. 	struct mkroom *br_room;
1132. 
1133. 	/*
1134. 	 * Return immediately if there is no branch to make or we have
1135. 	 * already made one.  This routine can be called twice when
1136. 	 * a special level is loaded that specifies an SSTAIR location
1137. 	 * as a favored spot for a branch.
1138. 	 */
1139. 	if (!br || made_branch) return;
1140. 
1141. 	if (!x) {	/* find random coordinates for branch */
1142. 	    br_room = find_branch_room(&m);
1143. 	    x = m.x;
1144. 	    y = m.y;
1145. 	} else {
1146. 	    br_room = pos_to_room(x, y);
1147. 	}
1148. 
1149. 	if (on_level(&br->end1, &u.uz)) {
1150. 	    /* we're on end1 */
1151. 	    make_stairs = br->type != BR_NO_END1;
1152. 	    dest = &br->end2;
1153. 	} else {
1154. 	    /* we're on end2 */
1155. 	    make_stairs = br->type != BR_NO_END2;
1156. 	    dest = &br->end1;
1157. 	}
1158. 
1159. 	if (br->type == BR_PORTAL) {
1160. 	    mkportal(x, y, dest->dnum, dest->dlevel);
1161. 	} else if (make_stairs) {
1162. 	    sstairs.sx = x;
1163. 	    sstairs.sy = y;
1164. 	    sstairs.up = (char) on_level(&br->end1, &u.uz) ?
1165. 					    br->end1_up : !br->end1_up;
1166. 	    assign_level(&sstairs.tolev, dest);
1167. 	    sstairs_room = br_room;
1168. 
1169. 	    levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN;
1170. 	    levl[x][y].typ = STAIRS;
1171. 	}
1172. 	/*
1173. 	 * Set made_branch to TRUE even if we didn't make a stairwell (i.e.
1174. 	 * make_stairs is false) since there is currently only one branch
1175. 	 * per level, if we failed once, we're going to fail again on the
1176. 	 * next call.
1177. 	 */
1178. 	made_branch = TRUE;
1179. }
1180. 
1181. STATIC_OVL boolean
1182. bydoor(x, y)
1183. register xchar x, y;
1184. {
1185. 	register int typ;
1186. 
1187. 	if (isok(x+1, y)) {
1188. 		typ = levl[x+1][y].typ;
1189. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1190. 	}
1191. 	if (isok(x-1, y)) {
1192. 		typ = levl[x-1][y].typ;
1193. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1194. 	}
1195. 	if (isok(x, y+1)) {
1196. 		typ = levl[x][y+1].typ;
1197. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1198. 	}
1199. 	if (isok(x, y-1)) {
1200. 		typ = levl[x][y-1].typ;
1201. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1202. 	}
1203. 	return FALSE;
1204. }
1205. 
1206. /* see whether it is allowable to create a door at [x,y] */
1207. int
1208. okdoor(x,y)
1209. register xchar x, y;
1210. {
1211. 	register boolean near_door = bydoor(x, y);
1212. 
1213. 	return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
1214. 			doorindex < DOORMAX && !near_door);
1215. }
1216. 
1217. void
1218. dodoor(x,y,aroom)
1219. register int x, y;
1220. register struct mkroom *aroom;
1221. {
1222. 	if(doorindex >= DOORMAX) {
1223. 		impossible("DOORMAX exceeded?");
1224. 		return;
1225. 	}
1226. 
1227. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
1228. }
1229. 
1230. boolean
1231. occupied(x, y)
1232. register xchar x, y;
1233. {
1234. 	return((boolean)(t_at(x, y)
1235. 		|| IS_FURNITURE(levl[x][y].typ)
1236. 		|| is_lava(x,y)
1237. 		|| is_pool(x,y)
1238. 		|| invocation_pos(x,y)
1239. 		));
1240. }
1241. 
1242. /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
1243. /* if tm != null, make trap at that location */
1244. void
1245. mktrap(num, mazeflag, croom, tm)
1246. register int num, mazeflag;
1247. register struct mkroom *croom;
1248. coord *tm;
1249. {
1250. 	register int kind;
1251. 	coord m;
1252. 
1253. 	/* no traps in pools */
1254. 	if (tm && is_pool(tm->x,tm->y)) return;
1255. 
1256. 	if (num > 0 && num < TRAPNUM) {
1257. 	    kind = num;
1258. #ifdef REINCARNATION
1259. 	} else if (Is_rogue_level(&u.uz)) {
1260. 	    switch (rn2(7)) {
1261. 		default: kind = BEAR_TRAP; break; /* 0 */
1262. 		case 1: kind = ARROW_TRAP; break;
1263. 		case 2: kind = DART_TRAP; break;
1264. 		case 3: kind = TRAPDOOR; break;
1265. 		case 4: kind = PIT; break;
1266. 		case 5: kind = SLP_GAS_TRAP; break;
1267. 		case 6: kind = RUST_TRAP; break;
1268. 	    }
1269. #endif
1270. 	} else if (Inhell && !rn2(5)) {
1271. 	    /* bias the frequency of fire traps in Gehennom */
1272. 	    kind = FIRE_TRAP;
1273. 	} else {
1274. 	    unsigned lvl = level_difficulty();
1275. 
1276. 	    do {
1277. 		kind = rnd(TRAPNUM-1);
1278. 		/* reject "too hard" traps */
1279. 		switch (kind) {
1280. 		    case MAGIC_PORTAL:
1281. 			kind = NO_TRAP; break;
1282. 		    case ROLLING_BOULDER_TRAP:
1283. 		    case SLP_GAS_TRAP:
1284. 			if (lvl < 2) kind = NO_TRAP; break;
1285. 		    case LEVEL_TELEP:
1286. 			if (lvl < 5 || level.flags.noteleport)
1287. 			    kind = NO_TRAP; break;
1288. 		    case SPIKED_PIT:
1289. 			if (lvl < 5) kind = NO_TRAP; break;
1290. 		    case LANDMINE:
1291. 			if (lvl < 6) kind = NO_TRAP; break;
1292. 		    case WEB:
1293. 			if (lvl < 7) kind = NO_TRAP; break;
1294. 		    case STATUE_TRAP:
1295. 		    case POLY_TRAP:
1296. 			if (lvl < 8) kind = NO_TRAP; break;
1297. 		    case FIRE_TRAP:
1298. 			if (!Inhell) kind = NO_TRAP; break;
1299. 		    case TELEP_TRAP:
1300. 			if (level.flags.noteleport) kind = NO_TRAP; break;
1301. 		    case HOLE:
1302. 			/* make these much less often than other traps */
1303. 			if (rn2(7)) kind = NO_TRAP; break;
1304. 		}
1305. 	    } while (kind == NO_TRAP);
1306. 	}
1307. 
1308. 	if ((kind == TRAPDOOR || kind == HOLE) && !Can_fall_thru(&u.uz))
1309. 		kind = ROCKTRAP;
1310. 
1311. 	if (tm)
1312. 	    m = *tm;
1313. 	else {
1314. 	    register int tryct = 0;
1315. 	    boolean avoid_boulder = (kind == PIT || kind == SPIKED_PIT ||
1316. 				     kind == TRAPDOOR || kind == HOLE);
1317. 
1318. 	    do {
1319. 		if (++tryct > 200)
1320. 		    return;
1321. 		if (mazeflag)
1322. 		    mazexy(&m);
1323. 		else if (!somexy(croom,&m))
1324. 		    return;
1325. 	    } while (occupied(m.x, m.y) ||
1326. 			(avoid_boulder && sobj_at(BOULDER, m.x, m.y)));
1327. 	}
1328. 
1329. 	(void) maketrap(m.x, m.y, kind);
1330. 	if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER],
1331. 						m.x, m.y, NO_MM_FLAGS);
1332. }
1333. 
1334. void
1335. mkstairs(x, y, up, croom)
1336. xchar x, y;
1337. char  up;
1338. struct mkroom *croom;
1339. {
1340. 	if (!x) {
1341. 	    impossible("mkstairs:  bogus stair attempt at <%d,%d>", x, y);
1342. 	    return;
1343. 	}
1344. 
1345. 	/*
1346. 	 * We can't make a regular stair off an end of the dungeon.  This
1347. 	 * attempt can happen when a special level is placed at an end and
1348. 	 * has an up or down stair specified in its description file.
1349. 	 */
1350. 	if ((dunlev(&u.uz) == 1 && up) ||
1351. 			(dunlev(&u.uz) == real_dunlevs_in_dungeon(&u.uz) && !up))
1352. 	    return;
1353. 
1354. 	if(up) {
1355. 		xupstair = x;
1356. 		yupstair = y;
1357. 		upstairs_room = croom;
1358. 	} else {
1359. 		xdnstair = x;
1360. 		ydnstair = y;
1361. 		dnstairs_room = croom;
1362. 	}
1363. 
1364. 	levl[x][y].typ = STAIRS;
1365. 	levl[x][y].ladder = up ? LA_UP : LA_DOWN;
1366. }
1367. 
1368. STATIC_OVL
1369. void
1370. mkfount(mazeflag,croom)
1371. register int mazeflag;
1372. register struct mkroom *croom;
1373. {
1374. 	coord m;
1375. 	register int tryct = 0;
1376. 
1377. 	do {
1378. 	    if(++tryct > 200) return;
1379. 	    if(mazeflag)
1380. 		mazexy(&m);
1381. 	    else
1382. 		if (!somexy(croom, &m))
1383. 		    return;
1384. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y));
1385. 
1386. 	/* Put a fountain at m.x, m.y */
1387. 	levl[m.x][m.y].typ = FOUNTAIN;
1388. 	/* Is it a "blessed" fountain? (affects drinking from fountain) */
1389. 	if(!rn2(7)) levl[m.x][m.y].blessedftn = 1;
1390. 
1391. 	level.flags.nfountains++;
1392. }
1393. 
1394. #ifdef SINKS
1395. STATIC_OVL void
1396. mksink(croom)
1397. register struct mkroom *croom;
1398. {
1399. 	coord m;
1400. 	register int tryct = 0;
1401. 
1402. 	do {
1403. 	    if(++tryct > 200) return;
1404. 	    if (!somexy(croom, &m))
1405. 		return;
1406. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y));
1407. 
1408. 	/* Put a sink at m.x, m.y */
1409. 	levl[m.x][m.y].typ = SINK;
1410. 
1411. 	level.flags.nsinks++;
1412. }
1413. 
1414. static void
1415. mktoilet(croom)
1416. register struct mkroom *croom;
1417. {
1418. 	coord m;
1419. 	register int tryct = 0;
1420. 
1421. 	do {
1422. 	    if(++tryct > 200) return;
1423. 	    if (!somexy(croom, &m))
1424. 		return;
1425. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y));
1426. 
1427. 	/* Put a toilet at m.x, m.y */
1428. 	levl[m.x][m.y].typ = TOILET;
1429. 
1430. 	level.flags.nsinks++; /* counted as a sink for sounds.c */
1431. }
1432. #endif /* SINKS */
1433. 
1434. STATIC_OVL void
1435. mkaltar(croom)
1436. register struct mkroom *croom;
1437. {
1438. 	coord m;
1439. 	register int tryct = 0;
1440. 	aligntyp al;
1441. 
1442. 	if(croom->rtype != OROOM) return;
1443. 
1444. 	do {
1445. 	    if(++tryct > 200) return;
1446. 	    if (!somexy(croom, &m))
1447. 		return;
1448. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y));
1449. 
1450. 	/* Put an altar at m.x, m.y */
1451. 	levl[m.x][m.y].typ = ALTAR;
1452. 
1453. 	/* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
1454. 	al = rn2((int)A_LAWFUL+2) - 1;
1455. 	levl[m.x][m.y].altarmask = Align2amask( al );
1456. }
1457. 
1458. static void
1459. mkgrave(croom)
1460. struct mkroom *croom;
1461. {
1462. 	coord m;
1463. 	register int tryct = 0;
1464. 	register struct obj *otmp;
1465. 	boolean dobell = !rn2(10);
1466. 
1467. 
1468. 	if(croom->rtype != OROOM) return;
1469. 
1470. 	do {
1471. 	    if(++tryct > 200) return;
1472. 	    if (!somexy(croom, &m))
1473. 		return;
1474. 	} while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1475. 
1476. 	/* Put a grave at m.x, m.y */
1477. 	make_grave(m.x, m.y, dobell ? "Saved by the bell!" : (char *) 0);
1478. 
1479. 	/* Possibly fill it with objects */
1480. 	if (!rn2(3)) (void) mkgold(0L, m.x, m.y);
1481. 	for (tryct = rn2(5); tryct; tryct--) {
1482. 	    otmp = mkobj(RANDOM_CLASS, TRUE);
1483. 	    if (!otmp) return;
1484. 	    curse(otmp);
1485. 	    otmp->ox = m.x;
1486. 	    otmp->oy = m.y;
1487. 	    add_to_buried(otmp);
1488. 	}
1489. 
1490. 	/* Leave a bell, in case we accidentally buried someone alive */
1491. 	if (dobell) (void) mksobj_at(BELL, m.x, m.y, TRUE, FALSE);
1492. 	return;
1493. }
1494. 
1495. /* maze levels have slightly different constraints from normal levels */
1496. #define x_maze_min 2
1497. #define y_maze_min 2
1498. /*
1499.  * Major level transmutation: add a set of stairs (to the Sanctum) after
1500.  * an earthquake that leaves behind a a new topology, centered at inv_pos.
1501.  * Assumes there are no rooms within the invocation area and that inv_pos
1502.  * is not too close to the edge of the map.  Also assume the hero can see,
1503.  * which is guaranteed for normal play due to the fact that sight is needed
1504.  * to read the Book of the Dead.
1505.  */
1506. void
1507. mkinvokearea()
1508. {
1509.     int dist;
1510.     xchar xmin = inv_pos.x, xmax = inv_pos.x;
1511.     xchar ymin = inv_pos.y, ymax = inv_pos.y;
1512.     register xchar i;
1513. 
1514.     pline_The("floor shakes violently under you!");
1515.     pline_The("walls around you begin to bend and crumble!");
1516.     display_nhwindow(WIN_MESSAGE, TRUE);
1517. 
1518.     mkinvpos(xmin, ymin, 0);		/* middle, before placing stairs */
1519. 
1520.     for(dist = 1; dist < 7; dist++) {
1521. 	xmin--; xmax++;
1522. 
1523. 	/* top and bottom */
1524. 	if(dist != 3) { /* the area is wider that it is high */
1525. 	    ymin--; ymax++;
1526. 	    for(i = xmin+1; i < xmax; i++) {
1527. 		mkinvpos(i, ymin, dist);
1528. 		mkinvpos(i, ymax, dist);
1529. 	    }
1530. 	}
1531. 
1532. 	/* left and right */
1533. 	for(i = ymin; i <= ymax; i++) {
1534. 	    mkinvpos(xmin, i, dist);
1535. 	    mkinvpos(xmax, i, dist);
1536. 	}
1537. 
1538. 	flush_screen(1);	/* make sure the new glyphs shows up */
1539. 	delay_output();
1540.     }
1541. 
1542.     You("are standing at the top of a stairwell leading down!");
1543.     mkstairs(u.ux, u.uy, 0, (struct mkroom *)0); /* down */
1544.     newsym(u.ux, u.uy);
1545.     vision_full_recalc = 1;	/* everything changed */
1546. }
1547. 
1548. /* Change level topology.  Boulders in the vicinity are eliminated.
1549.  * Temporarily overrides vision in the name of a nice effect.
1550.  */
1551. STATIC_OVL void
1552. mkinvpos(x,y,dist)
1553. xchar x,y;
1554. int dist;
1555. {
1556.     struct trap *ttmp;
1557.     struct obj *otmp;
1558.     boolean make_rocks;
1559.     register struct rm *lev = &levl[x][y];
1560. 
1561.     /* clip at existing map borders if necessary */
1562.     if (!within_bounded_area(x, y, x_maze_min + 1, y_maze_min + 1,
1563. 				   x_maze_max - 1, y_maze_max - 1)) {
1564. 	/* only outermost 2 columns and/or rows may be truncated due to edge */
1565. 	if (dist < (7 - 2))
1566. 	    panic("mkinvpos: <%d,%d> (%d) off map edge!", x, y, dist);
1567. 	return;
1568.     }
1569. 
1570.     /* clear traps */
1571.     if ((ttmp = t_at(x,y)) != 0) deltrap(ttmp);
1572. 
1573.     /* clear boulders; leave some rocks for non-{moat|trap} locations */
1574.     make_rocks = (dist != 1 && dist != 4 && dist != 5) ? TRUE : FALSE;
1575.     while ((otmp = sobj_at(BOULDER, x, y)) != 0) {
1576. 	if (make_rocks) {
1577. 	    fracture_rock(otmp);
1578. 	    make_rocks = FALSE;		/* don't bother with more rocks */
1579. 	} else {
1580. 	    obj_extract_self(otmp);
1581. 	    obfree(otmp, (struct obj *)0);
1582. 	}
1583.     }
1584.     unblock_point(x,y);	/* make sure vision knows this location is open */
1585. 
1586.     /* fake out saved state */
1587.     lev->seenv = 0;
1588.     lev->doormask = 0;
1589.     if(dist < 6) lev->lit = TRUE;
1590.     lev->waslit = TRUE;
1591.     lev->horizontal = FALSE;
1592.     viz_array[y][x] = (dist < 6 ) ?
1593. 	(IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
1594. 	COULD_SEE;
1595. 
1596.     switch(dist) {
1597.     case 1: /* fire traps */
1598. 	if (is_pool(x,y)) break;
1599. 	lev->typ = ROOM;
1600. 	ttmp = maketrap(x, y, FIRE_TRAP);
1601. 	if (ttmp) ttmp->tseen = TRUE;
1602. 	break;
1603.     case 0: /* lit room locations */
1604.     case 2:
1605.     case 3:
1606.     case 6: /* unlit room locations */
1607. 	lev->typ = ROOM;
1608. 	break;
1609.     case 4: /* pools (aka a wide moat) */
1610.     case 5:
1611. 	lev->typ = MOAT;
1612. 	/* No kelp! */
1613. 	break;
1614.     default:
1615. 	impossible("mkinvpos called with dist %d", dist);
1616. 	break;
1617.     }
1618. 
1619.     /* display new value of position; could have a monster/object on it */
1620.     newsym(x,y);
1621. }
1622. 
1623. /*
1624.  * The portal to Ludios is special.  The entrance can only occur within a
1625.  * vault in the main dungeon at a depth greater than 10.  The Ludios branch
1626.  * structure reflects this by having a bogus "source" dungeon:  the value
1627.  * of n_dgns (thus, Is_branchlev() will never find it).
1628.  *
1629.  * Ludios will remain isolated until the branch is corrected by this function.
1630.  */
1631. STATIC_OVL void
1632. mk_knox_portal(x, y)
1633. xchar x, y;
1634. {
1635. 	extern int n_dgns;		/* from dungeon.c */
1636. 	d_level *source;
1637. 	branch *br;
1638. 	schar u_depth;
1639. 
1640. 	br = dungeon_branch("Fort Ludios");
1641. 	if (on_level(&knox_level, &br->end1)) {
1642. 	    source = &br->end2;
1643. 	} else {
1644. 	    /* disallow Knox branch on a level with one branch already */
1645. 	    if(Is_branchlev(&u.uz))
1646. 		return;
1647. 	    source = &br->end1;
1648. 	}
1649. 
1650. 	/* Already set or 2/3 chance of deferring until a later level. */
1651. 	if (source->dnum < n_dgns || (rn2(3)
1652. #ifdef WIZARD
1653. 				      && !wizard
1654. #endif
1655. 				      )) return;
1656. 
1657. 	if (! (u.uz.dnum == oracle_level.dnum	    /* in main dungeon */
1658. 		&& !at_dgn_entrance("The Quest")    /* but not Quest's entry */
1659. 		&& (u_depth = depth(&u.uz)) > 10    /* beneath 10 */
1660. 		&& u_depth < depth(&medusa_level))) /* and above Medusa */
1661. 	    return;
1662. 
1663. 	/* Adjust source to be current level and re-insert branch. */
1664. 	*source = u.uz;
1665. 	insert_branch(br, TRUE);
1666. 
1667. #ifdef DEBUG
1668. 	pline("Made knox portal.");
1669. #endif
1670. 	place_branch(br, x, y);
1671. }
1672. 
1673. /*mklev.c*/

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.