Wikihack
Advertisement

Below is the full text to src/mklev.c from NetHack 3.4.3. To link to a particular line, write [[mklev.c#line123]], for example.

Top of file[]

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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.   #endif
25.   STATIC_DCL void FDECL(mkaltar,(struct mkroom *));
26.   STATIC_DCL void FDECL(mkgrave,(struct mkroom *));
27.   STATIC_DCL void NDECL(makevtele);
28.   STATIC_DCL void NDECL(clear_level_structures);
29.   STATIC_DCL void NDECL(makelevel);
30.   STATIC_DCL void NDECL(mineralize);
31.   STATIC_DCL boolean FDECL(bydoor,(XCHAR_P,XCHAR_P));
32.   STATIC_DCL struct mkroom *FDECL(find_branch_room, (coord *));
33.   STATIC_DCL struct mkroom *FDECL(pos_to_room, (XCHAR_P, XCHAR_P));
34.   STATIC_DCL boolean FDECL(place_niche,(struct mkroom *,int*,int*,int*));
35.   STATIC_DCL void FDECL(makeniche,(int));
36.   STATIC_DCL void NDECL(make_niches);
37.   
38.   STATIC_PTR int FDECL( CFDECLSPEC do_comp,(const genericptr,const genericptr));
39.   
40.   STATIC_DCL void FDECL(dosdoor,(XCHAR_P,XCHAR_P,struct mkroom *,int));
41.   STATIC_DCL void FDECL(join,(int,int,BOOLEAN_P));
42.   STATIC_DCL void FDECL(do_room_or_subroom, (struct mkroom *,int,int,int,int,
43.   				       BOOLEAN_P,SCHAR_P,BOOLEAN_P,BOOLEAN_P));
44.   STATIC_DCL void NDECL(makerooms);
45.   STATIC_DCL void FDECL(finddpos,(coord *,XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P));
46.   STATIC_DCL void FDECL(mkinvpos, (XCHAR_P,XCHAR_P,int));
47.   STATIC_DCL void FDECL(mk_knox_portal, (XCHAR_P,XCHAR_P));
48.   
49.   #define create_vault()	create_room(-1, -1, 2, 2, -1, -1, VAULT, TRUE)
50.   #define init_vault()	vault_x = -1
51.   #define do_vault()	(vault_x != -1)
52.   static xchar		vault_x, vault_y;
53.   boolean goldseen;
54.   static boolean made_branch;	/* used only during level creation */

do_comp[]

55.   
56.   /* Args must be (const genericptr) so that qsort will always be happy. */
57.   
58.   STATIC_PTR int CFDECLSPEC
59.   do_comp(vx,vy)
60.   const genericptr vx;
61.   const genericptr vy;
62.   {
63.   #ifdef LINT
64.   /* lint complains about possible pointer alignment problems, but we know
65.      that vx and vy are always properly aligned. Hence, the following
66.      bogus definition:
67.   */
68.   	return (vx == vy) ? 0 : -1;
69.   #else
70.   	register const struct mkroom *x, *y;
71.   
72.   	x = (const struct mkroom *)vx;
73.   	y = (const struct mkroom *)vy;
74.   	if(x->lx < y->lx) return(-1);
75.   	return(x->lx > y->lx);
76.   #endif /* LINT */
77.   }
78.   

finddpos[]

79.   STATIC_OVL void
80.   finddpos(cc, xl,yl,xh,yh)
81.   coord *cc;
82.   xchar xl,yl,xh,yh;
83.   {
84.   	register xchar x, y;
85.   
86.   	x = (xl == xh) ? xl : (xl + rn2(xh-xl+1));
87.   	y = (yl == yh) ? yl : (yl + rn2(yh-yl+1));
88.   	if(okdoor(x, y))
89.   		goto gotit;
90.   
91.   	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
92.   		if(okdoor(x, y))
93.   			goto gotit;
94.   
95.   	for(x = xl; x <= xh; x++) for(y = yl; y <= yh; y++)
96.   		if(IS_DOOR(levl[x][y].typ) || levl[x][y].typ == SDOOR)
97.   			goto gotit;
98.   	/* cannot find something reasonable -- strange */
99.   	x = xl;
100.  	y = yh;
101.  gotit:
102.  	cc->x = x;
103.  	cc->y = y;
104.  	return;
105.  }
106.  

sort_rooms[]

107.  void
108.  sort_rooms()
109.  {
110.  #if defined(SYSV) || defined(DGUX)
111.  	qsort((genericptr_t) rooms, (unsigned)nroom, sizeof(struct mkroom), do_comp);
112.  #else
113.  	qsort((genericptr_t) rooms, nroom, sizeof(struct mkroom), do_comp);
114.  #endif
115.  }
116.  

do_room_or_subroom[]

117.  STATIC_OVL void
118.  do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit, rtype, special, is_room)
119.      register struct mkroom *croom;
120.      int lowx, lowy;
121.      register int hix, hiy;
122.      boolean lit;
123.      schar rtype;
124.      boolean special;
125.      boolean is_room;
126.  {
127.  	register int x, y;
128.  	struct rm *lev;
129.  
130.  	/* locations might bump level edges in wall-less rooms */
131.  	/* add/subtract 1 to allow for edge locations */
132.  	if(!lowx) lowx++;
133.  	if(!lowy) lowy++;
134.  	if(hix >= COLNO-1) hix = COLNO-2;
135.  	if(hiy >= ROWNO-1) hiy = ROWNO-2;
136.  
137.  	if(lit) {
138.  		for(x = lowx-1; x <= hix+1; x++) {
139.  			lev = &levl[x][max(lowy-1,0)];
140.  			for(y = lowy-1; y <= hiy+1; y++)
141.  				lev++->lit = 1;
142.  		}
143.  		croom->rlit = 1;
144.  	} else
145.  		croom->rlit = 0;
146.  
147.  	croom->lx = lowx;
148.  	croom->hx = hix;
149.  	croom->ly = lowy;
150.  	croom->hy = hiy;
151.  	croom->rtype = rtype;
152.  	croom->doorct = 0;
153.  	/* if we're not making a vault, doorindex will still be 0
154.  	 * if we are, we'll have problems adding niches to the previous room
155.  	 * unless fdoor is at least doorindex
156.  	 */
157.  	croom->fdoor = doorindex;
158.  	croom->irregular = FALSE;
159.  
160.  	croom->nsubrooms = 0;
161.  	croom->sbrooms[0] = (struct mkroom *) 0;
162.  	if (!special) {
163.  	    for(x = lowx-1; x <= hix+1; x++)
164.  		for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
165.  		    levl[x][y].typ = HWALL;
166.  		    levl[x][y].horizontal = 1;	/* For open/secret doors. */
167.  		}
168.  	    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
169.  		for(y = lowy; y <= hiy; y++) {
170.  		    levl[x][y].typ = VWALL;
171.  		    levl[x][y].horizontal = 0;	/* For open/secret doors. */
172.  		}
173.  	    for(x = lowx; x <= hix; x++) {
174.  		lev = &levl[x][lowy];
175.  		for(y = lowy; y <= hiy; y++)
176.  		    lev++->typ = ROOM;
177.  	    }
178.  	    if (is_room) {
179.  		levl[lowx-1][lowy-1].typ = TLCORNER;
180.  		levl[hix+1][lowy-1].typ = TRCORNER;
181.  		levl[lowx-1][hiy+1].typ = BLCORNER;
182.  		levl[hix+1][hiy+1].typ = BRCORNER;
183.  	    } else {	/* a subroom */
184.  		wallification(lowx-1, lowy-1, hix+1, hiy+1);
185.  	    }
186.  	}
187.  }
188.  
189.  

add_room[]

190.  void
191.  add_room(lowx, lowy, hix, hiy, lit, rtype, special)
192.  register int lowx, lowy, hix, hiy;
193.  boolean lit;
194.  schar rtype;
195.  boolean special;
196.  {
197.  	register struct mkroom *croom;
198.  
199.  	croom = &rooms[nroom];
200.  	do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,
201.  					    rtype, special, (boolean) TRUE);
202.  	croom++;
203.  	croom->hx = -1;
204.  	nroom++;
205.  }
206.  

add_subroom[]

207.  void
208.  add_subroom(proom, lowx, lowy, hix, hiy, lit, rtype, special)
209.  struct mkroom *proom;
210.  register int lowx, lowy, hix, hiy;
211.  boolean lit;
212.  schar rtype;
213.  boolean special;
214.  {
215.  	register struct mkroom *croom;
216.  
217.  	croom = &subrooms[nsubroom];
218.  	do_room_or_subroom(croom, lowx, lowy, hix, hiy, lit,
219.  					    rtype, special, (boolean) FALSE);
220.  	proom->sbrooms[proom->nsubrooms++] = croom;
221.  	croom++;
222.  	croom->hx = -1;
223.  	nsubroom++;
224.  }
225.  

makerooms[]

226.  STATIC_OVL void
227.  makerooms()
228.  {
229.  	boolean tried_vault = FALSE;
230.  
231.  	/* make rooms until satisfied */
232.  	/* rnd_rect() will returns 0 if no more rects are available... */
233.  	while(nroom < MAXNROFROOMS && rnd_rect()) {
234.  		if(nroom >= (MAXNROFROOMS/6) && rn2(2) && !tried_vault) {
235.  			tried_vault = TRUE;
236.  			if (create_vault()) {
237.  				vault_x = rooms[nroom].lx;
238.  				vault_y = rooms[nroom].ly;
239.  				rooms[nroom].hx = -1;
240.  			}
241.  		} else
242.  		    if (!create_room(-1, -1, -1, -1, -1, -1, OROOM, -1))
243.  			return;
244.  	}
245.  	return;
246.  }
247.  

join[]

248.  STATIC_OVL void
249.  join(a,b,nxcor)
250.  register int a, b;
251.  boolean nxcor;
252.  {
253.  	coord cc,tt, org, dest;
254.  	register xchar tx, ty, xx, yy;
255.  	register struct mkroom *croom, *troom;
256.  	register int dx, dy;
257.  
258.  	croom = &rooms[a];
259.  	troom = &rooms[b];
260.  
261.  	/* find positions cc and tt for doors in croom and troom
262.  	   and direction for a corridor between them */
263.  
264.  	if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return;
265.  	if(troom->lx > croom->hx) {
266.  		dx = 1;
267.  		dy = 0;
268.  		xx = croom->hx+1;
269.  		tx = troom->lx-1;
270.  		finddpos(&cc, xx, croom->ly, xx, croom->hy);
271.  		finddpos(&tt, tx, troom->ly, tx, troom->hy);
272.  	} else if(troom->hy < croom->ly) {
273.  		dy = -1;
274.  		dx = 0;
275.  		yy = croom->ly-1;
276.  		finddpos(&cc, croom->lx, yy, croom->hx, yy);
277.  		ty = troom->hy+1;
278.  		finddpos(&tt, troom->lx, ty, troom->hx, ty);
279.  	} else if(troom->hx < croom->lx) {
280.  		dx = -1;
281.  		dy = 0;
282.  		xx = croom->lx-1;
283.  		tx = troom->hx+1;
284.  		finddpos(&cc, xx, croom->ly, xx, croom->hy);
285.  		finddpos(&tt, tx, troom->ly, tx, troom->hy);
286.  	} else {
287.  		dy = 1;
288.  		dx = 0;
289.  		yy = croom->hy+1;
290.  		ty = troom->ly-1;
291.  		finddpos(&cc, croom->lx, yy, croom->hx, yy);
292.  		finddpos(&tt, troom->lx, ty, troom->hx, ty);
293.  	}
294.  	xx = cc.x;
295.  	yy = cc.y;
296.  	tx = tt.x - dx;
297.  	ty = tt.y - dy;
298.  	if(nxcor && levl[xx+dx][yy+dy].typ)
299.  		return;
300.  	if (okdoor(xx,yy) || !nxcor)
301.  	    dodoor(xx,yy,croom);
302.  
303.  	org.x  = xx+dx; org.y  = yy+dy;
304.  	dest.x = tx; dest.y = ty;
305.  
306.  	if (!dig_corridor(&org, &dest, nxcor,
307.  			level.flags.arboreal ? ROOM : CORR, STONE))
308.  	    return;
309.  
310.  	/* we succeeded in digging the corridor */
311.  	if (okdoor(tt.x, tt.y) || !nxcor)
312.  	    dodoor(tt.x, tt.y, troom);
313.  
314.  	if(smeq[a] < smeq[b])
315.  		smeq[b] = smeq[a];
316.  	else
317.  		smeq[a] = smeq[b];
318.  }
319.  

makecorridors[]

320.  void
321.  makecorridors()
322.  {
323.  	int a, b, i;
324.  	boolean any = TRUE;
325.  
326.  	for(a = 0; a < nroom-1; a++) {
327.  		join(a, a+1, FALSE);
328.  		if(!rn2(50)) break; /* allow some randomness */
329.  	}
330.  	for(a = 0; a < nroom-2; a++)
331.  	    if(smeq[a] != smeq[a+2])
332.  		join(a, a+2, FALSE);
333.  	for(a = 0; any && a < nroom; a++) {
334.  	    any = FALSE;
335.  	    for(b = 0; b < nroom; b++)
336.  		if(smeq[a] != smeq[b]) {
337.  		    join(a, b, FALSE);
338.  		    any = TRUE;
339.  		}
340.  	}
341.  	if(nroom > 2)
342.  	    for(i = rn2(nroom) + 4; i; i--) {
343.  		a = rn2(nroom);
344.  		b = rn2(nroom-2);
345.  		if(b >= a) b += 2;
346.  		join(a, b, TRUE);
347.  	    }
348.  }
349.  

add_door[]

350.  void
351.  add_door(x,y,aroom)
352.  register int x, y;
353.  register struct mkroom *aroom;
354.  {
355.  	register struct mkroom *broom;
356.  	register int tmp;
357.  
358.  	aroom->doorct++;
359.  	broom = aroom+1;
360.  	if(broom->hx < 0)
361.  		tmp = doorindex;
362.  	else
363.  		for(tmp = doorindex; tmp > broom->fdoor; tmp--)
364.  			doors[tmp] = doors[tmp-1];
365.  	doorindex++;
366.  	doors[tmp].x = x;
367.  	doors[tmp].y = y;
368.  	for( ; broom->hx >= 0; broom++) broom->fdoor++;
369.  }
370.  

dosdoor[]

371.  STATIC_OVL void
372.  dosdoor(x,y,aroom,type)
373.  register xchar x, y;
374.  register struct mkroom *aroom;
375.  register int type;
376.  {
377.  	boolean shdoor = ((*in_rooms(x, y, SHOPBASE))? TRUE : FALSE);
378.  
379.  	if(!IS_WALL(levl[x][y].typ)) /* avoid SDOORs on already made doors */
380.  		type = DOOR;
381.  	levl[x][y].typ = type;
382.  	if(type == DOOR) {
383.  	    if(!rn2(3)) {      /* is it a locked door, closed, or a doorway? */
384.  		if(!rn2(5))
385.  		    levl[x][y].doormask = D_ISOPEN;
386.  		else if(!rn2(6))
387.  		    levl[x][y].doormask = D_LOCKED;
388.  		else
389.  		    levl[x][y].doormask = D_CLOSED;
390.  
391.  		if (levl[x][y].doormask != D_ISOPEN && !shdoor &&
392.  		    level_difficulty() >= 5 && !rn2(25))
393.  		    levl[x][y].doormask |= D_TRAPPED;
394.  	    } else
395.  #ifdef STUPID
396.  		if (shdoor)
397.  			levl[x][y].doormask = D_ISOPEN;
398.  		else
399.  			levl[x][y].doormask = D_NODOOR;
400.  #else
401.  		levl[x][y].doormask = (shdoor ? D_ISOPEN : D_NODOOR);
402.  #endif
403.  	    if(levl[x][y].doormask & D_TRAPPED) {
404.  		struct monst *mtmp;
405.  
406.  		if (level_difficulty() >= 9 && !rn2(5) &&
407.  		   !((mvitals[PM_SMALL_MIMIC].mvflags & G_GONE) &&
408.  		     (mvitals[PM_LARGE_MIMIC].mvflags & G_GONE) &&
409.  		     (mvitals[PM_GIANT_MIMIC].mvflags & G_GONE))) {
410.  		    /* make a mimic instead */
411.  		    levl[x][y].doormask = D_NODOOR;
412.  		    mtmp = makemon(mkclass(S_MIMIC,0), x, y, NO_MM_FLAGS);
413.  		    if (mtmp)
414.  			set_mimic_sym(mtmp);
415.  		}
416.  	    }
417.  	    /* newsym(x,y); */
418.  	} else { /* SDOOR */
419.  		if(shdoor || !rn2(5))	levl[x][y].doormask = D_LOCKED;
420.  		else			levl[x][y].doormask = D_CLOSED;
421.  
422.  		if(!shdoor && level_difficulty() >= 4 && !rn2(20))
423.  		    levl[x][y].doormask |= D_TRAPPED;
424.  	}
425.  
426.  	add_door(x,y,aroom);
427.  }
428.  

place_niche[]

429.  STATIC_OVL boolean
430.  place_niche(aroom,dy,xx,yy)
431.  register struct mkroom *aroom;
432.  int *dy, *xx, *yy;
433.  {
434.  	coord dd;
435.  
436.  	if(rn2(2)) {
437.  	    *dy = 1;
438.  	    finddpos(&dd, aroom->lx, aroom->hy+1, aroom->hx, aroom->hy+1);
439.  	} else {
440.  	    *dy = -1;
441.  	    finddpos(&dd, aroom->lx, aroom->ly-1, aroom->hx, aroom->ly-1);
442.  	}
443.  	*xx = dd.x;
444.  	*yy = dd.y;
445.  	return((boolean)((isok(*xx,*yy+*dy) && levl[*xx][*yy+*dy].typ == STONE)
446.  	    && (isok(*xx,*yy-*dy) && !IS_POOL(levl[*xx][*yy-*dy].typ)
447.  				  && !IS_FURNITURE(levl[*xx][*yy-*dy].typ))));
448.  }
449.  
450.  /* there should be one of these per trap, in the same order as trap.h */
451.  static NEARDATA const char *trap_engravings[TRAPNUM] = {
452.  			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
453.  			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
454.  			(char *)0, (char *)0, (char *)0, (char *)0,
455.  			/* 14..16: trap door, teleport, level-teleport */
456.  			"Vlad was here", "ad aerarium", "ad aerarium",
457.  			(char *)0, (char *)0, (char *)0, (char *)0, (char *)0,
458.  			(char *)0,
459.  };
460.  

makeniche[]

461.  STATIC_OVL void
462.  makeniche(trap_type)
463.  int trap_type;
464.  {
465.  	register struct mkroom *aroom;
466.  	register struct rm *rm;
467.  	register int vct = 8;
468.  	int dy, xx, yy;
469.  	register struct trap *ttmp;
470.  
471.  	if(doorindex < DOORMAX)
472.  	  while(vct--) {
473.  	    aroom = &rooms[rn2(nroom)];
474.  	    if(aroom->rtype != OROOM) continue;	/* not an ordinary room */
475.  	    if(aroom->doorct == 1 && rn2(5)) continue;
476.  	    if(!place_niche(aroom,&dy,&xx,&yy)) continue;
477.  
478.  	    rm = &levl[xx][yy+dy];
479.  	    if(trap_type || !rn2(4)) {
480.  
481.  		rm->typ = SCORR;
482.  		if(trap_type) {
483.  		    if((trap_type == HOLE || trap_type == TRAPDOOR)
484.  			&& !Can_fall_thru(&u.uz))
485.  			trap_type = ROCKTRAP;
486.  		    ttmp = maketrap(xx, yy+dy, trap_type);
487.  		    if (ttmp) {
488.  			if (trap_type != ROCKTRAP) ttmp->once = 1;
489.  			if (trap_engravings[trap_type]) {
490.  			    make_engr_at(xx, yy-dy,
491.  				     trap_engravings[trap_type], 0L, DUST);
492.  			    wipe_engr_at(xx, yy-dy, 5); /* age it a little */
493.  			}
494.  		    }
495.  		}
496.  		dosdoor(xx, yy, aroom, SDOOR);
497.  	    } else {
498.  		rm->typ = CORR;
499.  		if(rn2(7))
500.  		    dosdoor(xx, yy, aroom, rn2(5) ? SDOOR : DOOR);
501.  		else {
502.  		    if (!level.flags.noteleport)
503.  			(void) mksobj_at(SCR_TELEPORTATION,
504.  					 xx, yy+dy, TRUE, FALSE);
505.  		    if (!rn2(3)) (void) mkobj_at(0, xx, yy+dy, TRUE);
506.  		}
507.  	    }
508.  	    return;
509.  	}
510.  }
511.  

make_niches[]

512.  STATIC_OVL void
513.  make_niches()
514.  {
515.  	register int ct = rnd((nroom>>1) + 1), dep = depth(&u.uz);
516.  
517.  	boolean	ltptr = (!level.flags.noteleport && dep > 15),
518.  		vamp = (dep > 5 && dep < 25);
519.  
520.  	while(ct--) {
521.  		if (ltptr && !rn2(6)) {
522.  			ltptr = FALSE;
523.  			makeniche(LEVEL_TELEP);
524.  		} else if (vamp && !rn2(6)) {
525.  			vamp = FALSE;
526.  			makeniche(TRAPDOOR);
527.  		} else	makeniche(NO_TRAP);
528.  	}
529.  }
530.  

makevtele[]

531.  STATIC_OVL void
532.  makevtele()
533.  {
534.  	makeniche(TELEP_TRAP);
535.  }
536.  

clear_level_structures[]

537.  /* clear out various globals that keep information on the current level.
538.   * some of this is only necessary for some types of levels (maze, normal,
539.   * special) but it's easier to put it all in one place than make sure
540.   * each type initializes what it needs to separately.
541.   */
542.  STATIC_OVL void
543.  clear_level_structures()
544.  {
545.  	static struct rm zerorm = { cmap_to_glyph(S_stone),
546.  						0, 0, 0, 0, 0, 0, 0, 0 };
547.  	register int x,y;
548.  	register struct rm *lev;
549.  
550.  	for(x=0; x<COLNO; x++) {
551.  	    lev = &levl[x][0];
552.  	    for(y=0; y<ROWNO; y++) {
553.  		*lev++ = zerorm;
554.  #ifdef MICROPORT_BUG
555.  		level.objects[x][y] = (struct obj *)0;
556.  		level.monsters[x][y] = (struct monst *)0;
557.  #endif
558.  	    }
559.  	}
560.  #ifndef MICROPORT_BUG
561.  	(void) memset((genericptr_t)level.objects, 0, sizeof(level.objects));
562.  	(void) memset((genericptr_t)level.monsters, 0, sizeof(level.monsters));
563.  #endif
564.  	level.objlist = (struct obj *)0;
565.  	level.buriedobjlist = (struct obj *)0;
566.  	level.monlist = (struct monst *)0;
567.  	level.damagelist = (struct damage *)0;
568.  
569.  	level.flags.nfountains = 0;
570.  	level.flags.nsinks = 0;
571.  	level.flags.has_shop = 0;
572.  	level.flags.has_vault = 0;
573.  	level.flags.has_zoo = 0;
574.  	level.flags.has_court = 0;
575.  	level.flags.has_morgue = level.flags.graveyard = 0;
576.  	level.flags.has_beehive = 0;
577.  	level.flags.has_barracks = 0;
578.  	level.flags.has_temple = 0;
579.  	level.flags.has_swamp = 0;
580.  	level.flags.noteleport = 0;
581.  	level.flags.hardfloor = 0;
582.  	level.flags.nommap = 0;
583.  	level.flags.hero_memory = 1;
584.  	level.flags.shortsighted = 0;
585.  	level.flags.arboreal = 0;
586.  	level.flags.is_maze_lev = 0;
587.  	level.flags.is_cavernous_lev = 0;
588.  
589.  	nroom = 0;
590.  	rooms[0].hx = -1;
591.  	nsubroom = 0;
592.  	subrooms[0].hx = -1;
593.  	doorindex = 0;
594.  	init_rect();
595.  	init_vault();
596.  	xdnstair = ydnstair = xupstair = yupstair = 0;
597.  	sstairs.sx = sstairs.sy = 0;
598.  	xdnladder = ydnladder = xupladder = yupladder = 0;
599.  	made_branch = FALSE;
600.  	clear_regions();
601.  }
602.  

makelevel[]

603.  STATIC_OVL void
604.  makelevel()
605.  {
606.  	register struct mkroom *croom, *troom;
607.  	register int tryct;
608.  	register int x, y;
609.  	struct monst *tmonst;	/* always put a web with a spider */
610.  	branch *branchp;
611.  	int room_threshold;
612.  
613.  	if(wiz1_level.dlevel == 0) init_dungeons();
614.  	oinit();	/* assign level dependent obj probabilities */
615.  	clear_level_structures();
616.  
617.  	{
618.  	    register s_level *slev = Is_special(&u.uz);
619.  
620.  	    /* check for special levels */
621.  #ifdef REINCARNATION
622.  	    if (slev && !Is_rogue_level(&u.uz))
623.  #else
624.  	    if (slev)
625.  #endif
626.  	    {
627.  		    makemaz(slev->proto);
628.  		    return;
629.  	    } else if (dungeons[u.uz.dnum].proto[0]) {
630.  		    makemaz("");
631.  		    return;
632.  	    } else if (In_mines(&u.uz)) {
633.  		    makemaz("minefill");
634.  		    return;
635.  	    } else if (In_quest(&u.uz)) {
636.  		    char	fillname[9];
637.  		    s_level	*loc_lev;
638.  
639.  		    Sprintf(fillname, "%s-loca", urole.filecode);
640.  		    loc_lev = find_level(fillname);
641.  
642.  		    Sprintf(fillname, "%s-fil", urole.filecode);
643.  		    Strcat(fillname,
644.  			   (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b");
645.  		    makemaz(fillname);
646.  		    return;
647.  	    } else if(In_hell(&u.uz) ||
648.  		  (rn2(5) && u.uz.dnum == medusa_level.dnum
649.  			  && depth(&u.uz) > depth(&medusa_level))) {
650.  		    makemaz("");
651.  		    return;
652.  	    }
653.  	}
654.  
655.  	/* otherwise, fall through - it's a "regular" level. */
656.  
657.  #ifdef REINCARNATION
658.  	if (Is_rogue_level(&u.uz)) {
659.  		makeroguerooms();
660.  		makerogueghost();
661.  	} else
662.  #endif
663.  		makerooms();
664.  	sort_rooms();
665.  
666.  	/* construct stairs (up and down in different rooms if possible) */
667.  	croom = &rooms[rn2(nroom)];
668.  	if (!Is_botlevel(&u.uz))
669.  	     mkstairs(somex(croom), somey(croom), 0, croom);	/* down */
670.  	if (nroom > 1) {
671.  	    troom = croom;
672.  	    croom = &rooms[rn2(nroom-1)];
673.  	    if (croom == troom) croom++;
674.  	}
675.  
676.  	if (u.uz.dlevel != 1) {
677.  	    xchar sx, sy;
678.  	    do {
679.  		sx = somex(croom);
680.  		sy = somey(croom);
681.  	    } while(occupied(sx, sy));
682.  	    mkstairs(sx, sy, 1, croom);	/* up */
683.  	}
684.  
685.  	branchp = Is_branchlev(&u.uz);	/* possible dungeon branch */
686.  	room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed
687.  					     to allow a random special room */
688.  #ifdef REINCARNATION
689.  	if (Is_rogue_level(&u.uz)) goto skip0;
690.  #endif
691.  	makecorridors();
692.  	make_niches();
693.  
694.  	/* make a secret treasure vault, not connected to the rest */
695.  	if(do_vault()) {
696.  		xchar w,h;
697.  #ifdef DEBUG
698.  		debugpline("trying to make a vault...");
699.  #endif
700.  		w = 1;
701.  		h = 1;
702.  		if (check_room(&vault_x, &w, &vault_y, &h, TRUE)) {
703.  		    fill_vault:
704.  			add_room(vault_x, vault_y, vault_x+w,
705.  				 vault_y+h, TRUE, VAULT, FALSE);
706.  			level.flags.has_vault = 1;
707.  			++room_threshold;
708.  			fill_room(&rooms[nroom - 1], FALSE);
709.  			mk_knox_portal(vault_x+w, vault_y+h);
710.  			if(!level.flags.noteleport && !rn2(3)) makevtele();
711.  		} else if(rnd_rect() && create_vault()) {
712.  			vault_x = rooms[nroom].lx;
713.  			vault_y = rooms[nroom].ly;
714.  			if (check_room(&vault_x, &w, &vault_y, &h, TRUE))
715.  				goto fill_vault;
716.  			else
717.  				rooms[nroom].hx = -1;
718.  		}
719.  	}
720.  
721.      {
722.  	register int u_depth = depth(&u.uz);
723.  
724.  #ifdef WIZARD
725.  	if(wizard && nh_getenv("SHOPTYPE")) mkroom(SHOPBASE); else
726.  #endif
727.  	if (u_depth > 1 &&
728.  	    u_depth < depth(&medusa_level) &&
729.  	    nroom >= room_threshold &&
730.  	    rn2(u_depth) < 3) mkroom(SHOPBASE);
731.  	else if (u_depth > 4 && !rn2(6)) mkroom(COURT);
732.  	else if (u_depth > 5 && !rn2(8) &&
733.  	   !(mvitals[PM_LEPRECHAUN].mvflags & G_GONE)) mkroom(LEPREHALL);
734.  	else if (u_depth > 6 && !rn2(7)) mkroom(ZOO);
735.  	else if (u_depth > 8 && !rn2(5)) mkroom(TEMPLE);
736.  	else if (u_depth > 9 && !rn2(5) &&
737.  	   !(mvitals[PM_KILLER_BEE].mvflags & G_GONE)) mkroom(BEEHIVE);
738.  	else if (u_depth > 11 && !rn2(6)) mkroom(MORGUE);
739.  	else if (u_depth > 12 && !rn2(8)) mkroom(ANTHOLE);
740.  	else if (u_depth > 14 && !rn2(4) &&
741.  	   !(mvitals[PM_SOLDIER].mvflags & G_GONE)) mkroom(BARRACKS);
742.  	else if (u_depth > 15 && !rn2(6)) mkroom(SWAMP);
743.  	else if (u_depth > 16 && !rn2(8) &&
744.  	   !(mvitals[PM_COCKATRICE].mvflags & G_GONE)) mkroom(COCKNEST);
745.      }
746.  
747.  #ifdef REINCARNATION
748.  skip0:
749.  #endif
750.  	/* Place multi-dungeon branch. */
751.  	place_branch(branchp, 0, 0);
752.  
753.  	/* for each room: put things inside */
754.  	for(croom = rooms; croom->hx > 0; croom++) {
755.  		if(croom->rtype != OROOM) continue;
756.  
757.  		/* put a sleeping monster inside */
758.  		/* Note: monster may be on the stairs. This cannot be
759.  		   avoided: maybe the player fell through a trap door
760.  		   while a monster was on the stairs. Conclusion:
761.  		   we have to check for monsters on the stairs anyway. */
762.  
763.  		if(u.uhave.amulet || !rn2(3)) {
764.  		    x = somex(croom); y = somey(croom);
765.  		    tmonst = makemon((struct permonst *) 0, x,y,NO_MM_FLAGS);
766.  		    if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] &&
767.  			    !occupied(x, y))
768.  			(void) maketrap(x, y, WEB);
769.  		}
770.  		/* put traps and mimics inside */
771.  		goldseen = FALSE;
772.  		x = 8 - (level_difficulty()/6);
773.  		if (x <= 1) x = 2;
774.  		while (!rn2(x))
775.  		    mktrap(0,0,croom,(coord*)0);
776.  		if (!goldseen && !rn2(3))
777.  		    (void) mkgold(0L, somex(croom), somey(croom));
778.  #ifdef REINCARNATION
779.  		if(Is_rogue_level(&u.uz)) goto skip_nonrogue;
780.  #endif
781.  		if(!rn2(10)) mkfount(0,croom);
782.  #ifdef SINKS
783.  		if(!rn2(60)) mksink(croom);
784.  #endif
785.  		if(!rn2(60)) mkaltar(croom);
786.  		x = 80 - (depth(&u.uz) * 2);
787.  		if (x < 2) x = 2;
788.  		if(!rn2(x)) mkgrave(croom);
789.  
790.  		/* put statues inside */
791.  		if(!rn2(20))
792.  		    (void) mkcorpstat(STATUE, (struct monst *)0,
793.  				      (struct permonst *)0,
794.  				      somex(croom), somey(croom), TRUE);
795.  		/* put box/chest inside;
796.  		 *  40% chance for at least 1 box, regardless of number
797.  		 *  of rooms; about 5 - 7.5% for 2 boxes, least likely
798.  		 *  when few rooms; chance for 3 or more is neglible.
799.  		 */
800.  		if(!rn2(nroom * 5 / 2))
801.  		    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
802.  				     somex(croom), somey(croom), TRUE, FALSE);
803.  
804.  		/* maybe make some graffiti */
805.  		if(!rn2(27 + 3 * abs(depth(&u.uz)))) {
806.  		    char buf[BUFSZ];
807.  		    const char *mesg = random_engraving(buf);
808.  		    if (mesg) {
809.  			do {
810.  			    x = somex(croom);  y = somey(croom);
811.  			} while(levl[x][y].typ != ROOM && !rn2(40));
812.  			if (!(IS_POOL(levl[x][y].typ) ||
813.  			      IS_FURNITURE(levl[x][y].typ)))
814.  			    make_engr_at(x, y, mesg, 0L, MARK);
815.  		    }
816.  		}
817.  
818.  #ifdef REINCARNATION
819.  	skip_nonrogue:
820.  #endif
821.  		if(!rn2(3)) {
822.  		    (void) mkobj_at(0, somex(croom), somey(croom), TRUE);
823.  		    tryct = 0;
824.  		    while(!rn2(5)) {
825.  			if(++tryct > 100) {
826.  			    impossible("tryct overflow4");
827.  			    break;
828.  			}
829.  			(void) mkobj_at(0, somex(croom), somey(croom), TRUE);
830.  		    }
831.  		}
832.  	}
833.  }
834.  

Line 821 starts the script that generates items on the dungeon floor. It appears the probability of making an item is 1 in 3, with a 1 in 5 chance of making each additional item.

mineralize[]

835.  /*
836.   *	Place deposits of minerals (gold and misc gems) in the stone
837.   *	surrounding the rooms on the map.
838.   *	Also place kelp in water.
839.   */
840.  STATIC_OVL void
841.  mineralize()
842.  {
843.  	s_level *sp;
844.  	struct obj *otmp;
845.  	int goldprob, gemprob, x, y, cnt;
846.  
847.  
848.  	/* Place kelp, except on the plane of water */
849.  	if (In_endgame(&u.uz)) return;
850.  	for (x = 2; x < (COLNO - 2); x++)
851.  	    for (y = 1; y < (ROWNO - 1); y++)
852.  		if ((levl[x][y].typ == POOL && !rn2(10)) ||
853.  			(levl[x][y].typ == MOAT && !rn2(30)))
854.  		    (void) mksobj_at(KELP_FROND, x, y, TRUE, FALSE);
855.  
856.  	/* determine if it is even allowed;
857.  	   almost all special levels are excluded */
858.  	if (In_hell(&u.uz) || In_V_tower(&u.uz) ||
859.  #ifdef REINCARNATION
860.  		Is_rogue_level(&u.uz) ||
861.  #endif
862.  		level.flags.arboreal ||
863.  		((sp = Is_special(&u.uz)) != 0 && !Is_oracle_level(&u.uz)
864.  					&& (!In_mines(&u.uz) || sp->flags.town)
865.  	    )) return;
866.  
867.  	/* basic level-related probabilities */
868.  	goldprob = 20 + depth(&u.uz) / 3;
869.  	gemprob = goldprob / 4;
870.  
871.  	/* mines have ***MORE*** goodies - otherwise why mine? */
872.  	if (In_mines(&u.uz)) {
873.  	    goldprob *= 2;
874.  	    gemprob *= 3;
875.  	} else if (In_quest(&u.uz)) {
876.  	    goldprob /= 4;
877.  	    gemprob /= 6;
878.  	}
879.  
880.  	/*
881.  	 * Seed rock areas with gold and/or gems.
882.  	 * We use fairly low level object handling to avoid unnecessary
883.  	 * overhead from placing things in the floor chain prior to burial.
884.  	 */
885.  	for (x = 2; x < (COLNO - 2); x++)
886.  	  for (y = 1; y < (ROWNO - 1); y++)
887.  	    if (levl[x][y+1].typ != STONE) {	 /* <x,y> spot not eligible */
888.  		y += 2;		/* next two spots aren't eligible either */
889.  	    } else if (levl[x][y].typ != STONE) { /* this spot not eligible */
890.  		y += 1;		/* next spot isn't eligible either */
891.  	    } else if (!(levl[x][y].wall_info & W_NONDIGGABLE) &&
892.  		  levl[x][y-1].typ   == STONE &&
893.  		  levl[x+1][y-1].typ == STONE && levl[x-1][y-1].typ == STONE &&
894.  		  levl[x+1][y].typ   == STONE && levl[x-1][y].typ   == STONE &&
895.  		  levl[x+1][y+1].typ == STONE && levl[x-1][y+1].typ == STONE) {
896.  		if (rn2(1000) < goldprob) {
897.  		    if ((otmp = mksobj(GOLD_PIECE, FALSE, FALSE)) != 0) {
898.  			otmp->ox = x,  otmp->oy = y;
899.  			otmp->quan = 1L + rnd(goldprob * 3);
900.  			otmp->owt = weight(otmp);
901.  			if (!rn2(3)) add_to_buried(otmp);
902.  			else place_object(otmp, x, y);
903.  		    }
904.  		}
905.  		if (rn2(1000) < gemprob) {
906.  		    for (cnt = rnd(2 + dunlev(&u.uz) / 3); cnt > 0; cnt--)
907.  			if ((otmp = mkobj(GEM_CLASS, FALSE)) != 0) {
908.  			    if (otmp->otyp == ROCK) {
909.  				dealloc_obj(otmp);	/* discard it */
910.  			    } else {
911.  				otmp->ox = x,  otmp->oy = y;
912.  				if (!rn2(3)) add_to_buried(otmp);
913.  				else place_object(otmp, x, y);
914.  			    }
915.  		    }
916.  		}
917.  	    }
918.  }
919.  

mklev[]

920.  void
921.  mklev()
922.  {
923.  	struct mkroom *croom;
924.  
925.  	if(getbones()) return;
926.  	in_mklev = TRUE;
927.  	makelevel();
928.  	bound_digging();
929.  	mineralize();
930.  	in_mklev = FALSE;
931.  	/* has_morgue gets cleared once morgue is entered; graveyard stays
932.  	   set (graveyard might already be set even when has_morgue is clear
933.  	   [see fixup_special()], so don't update it unconditionally) */
934.  	if (level.flags.has_morgue)
935.  	    level.flags.graveyard = 1;
936.  	if (!level.flags.is_maze_lev) {
937.  	    for (croom = &rooms[0]; croom != &rooms[nroom]; croom++)
938.  #ifdef SPECIALIZATION
939.  		topologize(croom, FALSE);
940.  #else
941.  		topologize(croom);
942.  #endif
943.  	}
944.  	set_wall_state();
945.  }
946.  

topologize[]

947.  void
948.  #ifdef SPECIALIZATION
949.  topologize(croom, do_ordinary)
950.  register struct mkroom *croom;
951.  boolean do_ordinary;
952.  #else
953.  topologize(croom)
954.  register struct mkroom *croom;
955.  #endif
956.  {
957.  	register int x, y, roomno = (croom - rooms) + ROOMOFFSET;
958.  	register int lowx = croom->lx, lowy = croom->ly;
959.  	register int hix = croom->hx, hiy = croom->hy;
960.  #ifdef SPECIALIZATION
961.  	register schar rtype = croom->rtype;
962.  #endif
963.  	register int subindex, nsubrooms = croom->nsubrooms;
964.  
965.  	/* skip the room if already done; i.e. a shop handled out of order */
966.  	/* also skip if this is non-rectangular (it _must_ be done already) */
967.  	if ((int) levl[lowx][lowy].roomno == roomno || croom->irregular)
968.  	    return;
969.  #ifdef SPECIALIZATION
970.  # ifdef REINCARNATION
971.  	if (Is_rogue_level(&u.uz))
972.  	    do_ordinary = TRUE;		/* vision routine helper */
973.  # endif
974.  	if ((rtype != OROOM) || do_ordinary)
975.  #endif
976.  	{
977.  	    /* do innards first */
978.  	    for(x = lowx; x <= hix; x++)
979.  		for(y = lowy; y <= hiy; y++)
980.  #ifdef SPECIALIZATION
981.  		    if (rtype == OROOM)
982.  			levl[x][y].roomno = NO_ROOM;
983.  		    else
984.  #endif
985.  			levl[x][y].roomno = roomno;
986.  	    /* top and bottom edges */
987.  	    for(x = lowx-1; x <= hix+1; x++)
988.  		for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
989.  		    levl[x][y].edge = 1;
990.  		    if (levl[x][y].roomno)
991.  			levl[x][y].roomno = SHARED;
992.  		    else
993.  			levl[x][y].roomno = roomno;
994.  		}
995.  	    /* sides */
996.  	    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
997.  		for(y = lowy; y <= hiy; y++) {
998.  		    levl[x][y].edge = 1;
999.  		    if (levl[x][y].roomno)
1000. 			levl[x][y].roomno = SHARED;
1001. 		    else
1002. 			levl[x][y].roomno = roomno;
1003. 		}
1004. 	}
1005. 	/* subrooms */
1006. 	for (subindex = 0; subindex < nsubrooms; subindex++)
1007. #ifdef SPECIALIZATION
1008. 		topologize(croom->sbrooms[subindex], (rtype != OROOM));
1009. #else
1010. 		topologize(croom->sbrooms[subindex]);
1011. #endif
1012. }
1013. 

find_branch_room[]

1014. /* Find an unused room for a branch location. */
1015. STATIC_OVL struct mkroom *
1016. find_branch_room(mp)
1017.     coord *mp;
1018. {
1019.     struct mkroom *croom = 0;
1020. 
1021.     if (nroom == 0) {
1022. 	mazexy(mp);		/* already verifies location */
1023.     } else {
1024. 	/* not perfect - there may be only one stairway */
1025. 	if(nroom > 2) {
1026. 	    int tryct = 0;
1027. 
1028. 	    do
1029. 		croom = &rooms[rn2(nroom)];
1030. 	    while((croom == dnstairs_room || croom == upstairs_room ||
1031. 		  croom->rtype != OROOM) && (++tryct < 100));
1032. 	} else
1033. 	    croom = &rooms[rn2(nroom)];
1034. 
1035. 	do {
1036. 	    if (!somexy(croom, mp))
1037. 		impossible("Can't place branch!");
1038. 	} while(occupied(mp->x, mp->y) ||
1039. 	    (levl[mp->x][mp->y].typ != CORR && levl[mp->x][mp->y].typ != ROOM));
1040.     }
1041.     return croom;
1042. }
1043. 

pos_to_room[]

1044. /* Find the room for (x,y).  Return null if not in a room. */
1045. STATIC_OVL struct mkroom *
1046. pos_to_room(x, y)
1047.     xchar x, y;
1048. {
1049.     int i;
1050.     struct mkroom *curr;
1051. 
1052.     for (curr = rooms, i = 0; i < nroom; curr++, i++)
1053. 	if (inside_room(curr, x, y)) return curr;;
1054.     return (struct mkroom *) 0;
1055. }
1056. 
1057. 

place_branch[]

1058. /* If given a branch, randomly place a special stair or portal. */
1059. void
1060. place_branch(br, x, y)
1061. branch *br;	/* branch to place */
1062. xchar x, y;	/* location */
1063. {
1064. 	coord	      m;
1065. 	d_level	      *dest;
1066. 	boolean	      make_stairs;
1067. 	struct mkroom *br_room;
1068. 
1069. 	/*
1070. 	 * Return immediately if there is no branch to make or we have
1071. 	 * already made one.  This routine can be called twice when
1072. 	 * a special level is loaded that specifies an SSTAIR location
1073. 	 * as a favored spot for a branch.
1074. 	 */
1075. 	if (!br || made_branch) return;
1076. 
1077. 	if (!x) {	/* find random coordinates for branch */
1078. 	    br_room = find_branch_room(&m);
1079. 	    x = m.x;
1080. 	    y = m.y;
1081. 	} else {
1082. 	    br_room = pos_to_room(x, y);
1083. 	}
1084. 
1085. 	if (on_level(&br->end1, &u.uz)) {
1086. 	    /* we're on end1 */
1087. 	    make_stairs = br->type != BR_NO_END1;
1088. 	    dest = &br->end2;
1089. 	} else {
1090. 	    /* we're on end2 */
1091. 	    make_stairs = br->type != BR_NO_END2;
1092. 	    dest = &br->end1;
1093. 	}
1094. 
1095. 	if (br->type == BR_PORTAL) {
1096. 	    mkportal(x, y, dest->dnum, dest->dlevel);
1097. 	} else if (make_stairs) {
1098. 	    sstairs.sx = x;
1099. 	    sstairs.sy = y;
1100. 	    sstairs.up = (char) on_level(&br->end1, &u.uz) ?
1101. 					    br->end1_up : !br->end1_up;
1102. 	    assign_level(&sstairs.tolev, dest);
1103. 	    sstairs_room = br_room;
1104. 
1105. 	    levl[x][y].ladder = sstairs.up ? LA_UP : LA_DOWN;
1106. 	    levl[x][y].typ = STAIRS;
1107. 	}
1108. 	/*
1109. 	 * Set made_branch to TRUE even if we didn't make a stairwell (i.e.
1110. 	 * make_stairs is false) since there is currently only one branch
1111. 	 * per level, if we failed once, we're going to fail again on the
1112. 	 * next call.
1113. 	 */
1114. 	made_branch = TRUE;
1115. }
1116. 

bydoor[]

1117. STATIC_OVL boolean
1118. bydoor(x, y)
1119. register xchar x, y;
1120. {
1121. 	register int typ;
1122. 
1123. 	if (isok(x+1, y)) {
1124. 		typ = levl[x+1][y].typ;
1125. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1126. 	}
1127. 	if (isok(x-1, y)) {
1128. 		typ = levl[x-1][y].typ;
1129. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1130. 	}
1131. 	if (isok(x, y+1)) {
1132. 		typ = levl[x][y+1].typ;
1133. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1134. 	}
1135. 	if (isok(x, y-1)) {
1136. 		typ = levl[x][y-1].typ;
1137. 		if (IS_DOOR(typ) || typ == SDOOR) return TRUE;
1138. 	}
1139. 	return FALSE;
1140. }
1141. 

okdoor[]

1142. /* see whether it is allowable to create a door at [x,y] */
1143. int
1144. okdoor(x,y)
1145. register xchar x, y;
1146. {
1147. 	register boolean near_door = bydoor(x, y);
1148. 
1149. 	return((levl[x][y].typ == HWALL || levl[x][y].typ == VWALL) &&
1150. 			doorindex < DOORMAX && !near_door);
1151. }
1152. 

dodoor[]

1153. void
1154. dodoor(x,y,aroom)
1155. register int x, y;
1156. register struct mkroom *aroom;
1157. {
1158. 	if(doorindex >= DOORMAX) {
1159. 		impossible("DOORMAX exceeded?");
1160. 		return;
1161. 	}
1162. 
1163. 	dosdoor(x,y,aroom,rn2(8) ? DOOR : SDOOR);
1164. }
1165. 

occupied[]

1166. boolean
1167. occupied(x, y)
1168. register xchar x, y;
1169. {
1170. 	return((boolean)(t_at(x, y)
1171. 		|| IS_FURNITURE(levl[x][y].typ)
1172. 		|| is_lava(x,y)
1173. 		|| is_pool(x,y)
1174. 		|| invocation_pos(x,y)
1175. 		));
1176. }
1177. 

mktrap[]

1178. /* make a trap somewhere (in croom if mazeflag = 0 && !tm) */
1179. /* if tm != null, make trap at that location */
1180. void
1181. mktrap(num, mazeflag, croom, tm)
1182. register int num, mazeflag;
1183. register struct mkroom *croom;
1184. coord *tm;
1185. {
1186. 	register int kind;
1187. 	coord m;
1188. 
1189. 	/* no traps in pools */
1190. 	if (tm && is_pool(tm->x,tm->y)) return;
1191. 
1192. 	if (num > 0 && num < TRAPNUM) {
1193. 	    kind = num;
1194. #ifdef REINCARNATION
1195. 	} else if (Is_rogue_level(&u.uz)) {
1196. 	    switch (rn2(7)) {
1197. 		default: kind = BEAR_TRAP; break; /* 0 */
1198. 		case 1: kind = ARROW_TRAP; break;
1199. 		case 2: kind = DART_TRAP; break;
1200. 		case 3: kind = TRAPDOOR; break;
1201. 		case 4: kind = PIT; break;
1202. 		case 5: kind = SLP_GAS_TRAP; break;
1203. 		case 6: kind = RUST_TRAP; break;
1204. 	    }
1205. #endif
1206. 	} else if (Inhell && !rn2(5)) {
1207. 	    /* bias the frequency of fire traps in Gehennom */
1208. 	    kind = FIRE_TRAP;
1209. 	} else {
1210. 	    unsigned lvl = level_difficulty();
1211. 
1212. 	    do {
1213. 		kind = rnd(TRAPNUM-1);
1214. 		/* reject "too hard" traps */
1215. 		switch (kind) {
1216. 		    case MAGIC_PORTAL:
1217. 			kind = NO_TRAP; break;
1218. 		    case ROLLING_BOULDER_TRAP:
1219. 		    case SLP_GAS_TRAP:
1220. 			if (lvl < 2) kind = NO_TRAP; break;
1221. 		    case LEVEL_TELEP:
1222. 			if (lvl < 5 || level.flags.noteleport)
1223. 			    kind = NO_TRAP; break;
1224. 		    case SPIKED_PIT:
1225. 			if (lvl < 5) kind = NO_TRAP; break;
1226. 		    case LANDMINE:
1227. 			if (lvl < 6) kind = NO_TRAP; break;
1228. 		    case WEB:
1229. 			if (lvl < 7) kind = NO_TRAP; break;
1230. 		    case STATUE_TRAP:
1231. 		    case POLY_TRAP:
1232. 			if (lvl < 8) kind = NO_TRAP; break;
1233. 		    case FIRE_TRAP:
1234. 			if (!Inhell) kind = NO_TRAP; break;
1235. 		    case TELEP_TRAP:
1236. 			if (level.flags.noteleport) kind = NO_TRAP; break;
1237. 		    case HOLE:
1238. 			/* make these much less often than other traps */
1239. 			if (rn2(7)) kind = NO_TRAP; break;
1240. 		}
1241. 	    } while (kind == NO_TRAP);
1242. 	}
1243. 
1244. 	if ((kind == TRAPDOOR || kind == HOLE) && !Can_fall_thru(&u.uz))
1245. 		kind = ROCKTRAP;
1246. 
1247. 	if (tm)
1248. 	    m = *tm;
1249. 	else {
1250. 	    register int tryct = 0;
1251. 	    boolean avoid_boulder = (kind == PIT || kind == SPIKED_PIT ||
1252. 				     kind == TRAPDOOR || kind == HOLE);
1253. 
1254. 	    do {
1255. 		if (++tryct > 200)
1256. 		    return;
1257. 		if (mazeflag)
1258. 		    mazexy(&m);
1259. 		else if (!somexy(croom,&m))
1260. 		    return;
1261. 	    } while (occupied(m.x, m.y) ||
1262. 			(avoid_boulder && sobj_at(BOULDER, m.x, m.y)));
1263. 	}
1264. 
1265. 	(void) maketrap(m.x, m.y, kind);
1266. 	if (kind == WEB) (void) makemon(&mons[PM_GIANT_SPIDER],
1267. 						m.x, m.y, NO_MM_FLAGS);
1268. }
1269. 

mkstairs[]

1270. void
1271. mkstairs(x, y, up, croom)
1272. xchar x, y;
1273. char  up;
1274. struct mkroom *croom;
1275. {
1276. 	if (!x) {
1277. 	    impossible("mkstairs:  bogus stair attempt at <%d,%d>", x, y);
1278. 	    return;
1279. 	}
1280. 
1281. 	/*
1282. 	 * We can't make a regular stair off an end of the dungeon.  This
1283. 	 * attempt can happen when a special level is placed at an end and
1284. 	 * has an up or down stair specified in its description file.
1285. 	 */
1286. 	if ((dunlev(&u.uz) == 1 && up) ||
1287. 			(dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up))
1288. 	    return;
1289. 
1290. 	if(up) {
1291. 		xupstair = x;
1292. 		yupstair = y;
1293. 		upstairs_room = croom;
1294. 	} else {
1295. 		xdnstair = x;
1296. 		ydnstair = y;
1297. 		dnstairs_room = croom;
1298. 	}
1299. 
1300. 	levl[x][y].typ = STAIRS;
1301. 	levl[x][y].ladder = up ? LA_UP : LA_DOWN;
1302. }
1303. 

mkfount[]

1304. STATIC_OVL
1305. void
1306. mkfount(mazeflag,croom)
1307. register int mazeflag;
1308. register struct mkroom *croom;
1309. {
1310. 	coord m;
1311. 	register int tryct = 0;
1312. 
1313. 	do {
1314. 	    if(++tryct > 200) return;
1315. 	    if(mazeflag)
1316. 		mazexy(&m);
1317. 	    else
1318. 		if (!somexy(croom, &m))
1319. 		    return;
1320. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y));
1321. 
1322. 	/* Put a fountain at m.x, m.y */
1323. 	levl[m.x][m.y].typ = FOUNTAIN;
1324. 	/* Is it a "blessed" fountain? (affects drinking from fountain) */
1325. 	if(!rn2(7)) levl[m.x][m.y].blessedftn = 1;
1326. 
1327. 	level.flags.nfountains++;
1328. }
1329. 
1330. #ifdef SINKS

mksink[]

1331. STATIC_OVL void
1332. mksink(croom)
1333. register struct mkroom *croom;
1334. {
1335. 	coord m;
1336. 	register int tryct = 0;
1337. 
1338. 	do {
1339. 	    if(++tryct > 200) return;
1340. 	    if (!somexy(croom, &m))
1341. 		return;
1342. 	} while(occupied(m.x, m.y) || bydoor(m.x, m.y));
1343. 
1344. 	/* Put a sink at m.x, m.y */
1345. 	levl[m.x][m.y].typ = SINK;
1346. 
1347. 	level.flags.nsinks++;
1348. }
1349. #endif /* SINKS */
1350. 
1351. 

mkaltar[]

1352. STATIC_OVL void
1353. mkaltar(croom)
1354. register struct mkroom *croom;
1355. {
1356. 	coord m;
1357. 	register int tryct = 0;
1358. 	aligntyp al;
1359. 
1360. 	if (croom->rtype != OROOM) return;
1361. 
1362. 	do {
1363. 	    if(++tryct > 200) return;
1364. 	    if (!somexy(croom, &m))
1365. 		return;
1366. 	} while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1367. 
1368. 	/* Put an altar at m.x, m.y */
1369. 	levl[m.x][m.y].typ = ALTAR;
1370. 
1371. 	/* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
1372. 	al = rn2((int)A_LAWFUL+2) - 1;
1373. 	levl[m.x][m.y].altarmask = Align2amask( al );
1374. }
1375. 

mkgrave[]

1376. static void
1377. mkgrave(croom)
1378. struct mkroom *croom;
1379. {
1380. 	coord m;
1381. 	register int tryct = 0;
1382. 	register struct obj *otmp;
1383. 	boolean dobell = !rn2(10);
1384. 
1385. 
1386. 	if(croom->rtype != OROOM) return;
1387. 
1388. 	do {
1389. 	    if(++tryct > 200) return;
1390. 	    if (!somexy(croom, &m))
1391. 		return;
1392. 	} while (occupied(m.x, m.y) || bydoor(m.x, m.y));
1393. 
1394. 	/* Put a grave at m.x, m.y */
1395. 	make_grave(m.x, m.y, dobell ? "Saved by the bell!" : (char *) 0);
1396. 
1397. 	/* Possibly fill it with objects */
1398. 	if (!rn2(3)) (void) mkgold(0L, m.x, m.y);
1399. 	for (tryct = rn2(5); tryct; tryct--) {
1400. 	    otmp = mkobj(RANDOM_CLASS, TRUE);
1401. 	    if (!otmp) return;
1402. 	    curse(otmp);
1403. 	    otmp->ox = m.x;
1404. 	    otmp->oy = m.y;
1405. 	    add_to_buried(otmp);
1406. 	}
1407. 
1408. 	/* Leave a bell, in case we accidentally buried someone alive */
1409. 	if (dobell) (void) mksobj_at(BELL, m.x, m.y, TRUE, FALSE);
1410. 	return;
1411. }
1412. 
1413. 
1414. /* maze levels have slightly different constraints from normal levels */
1415. #define x_maze_min 2
1416. #define y_maze_min 2

mkinvokearea[]

1417. /*
1418.  * Major level transmutation: add a set of stairs (to the Sanctum) after
1419.  * an earthquake that leaves behind a a new topology, centered at inv_pos.
1420.  * Assumes there are no rooms within the invocation area and that inv_pos
1421.  * is not too close to the edge of the map.  Also assume the hero can see,
1422.  * which is guaranteed for normal play due to the fact that sight is needed
1423.  * to read the Book of the Dead.
1424.  */
1425. void
1426. mkinvokearea()
1427. {
1428.     int dist;
1429.     xchar xmin = inv_pos.x, xmax = inv_pos.x;
1430.     xchar ymin = inv_pos.y, ymax = inv_pos.y;
1431.     register xchar i;
1432. 
1433.     pline_The("floor shakes violently under you!");
1434.     pline_The("walls around you begin to bend and crumble!");
1435.     display_nhwindow(WIN_MESSAGE, TRUE);
1436. 
1437.     mkinvpos(xmin, ymin, 0);		/* middle, before placing stairs */
1438. 
1439.     for(dist = 1; dist < 7; dist++) {
1440. 	xmin--; xmax++;
1441. 
1442. 	/* top and bottom */
1443. 	if(dist != 3) { /* the area is wider that it is high */
1444. 	    ymin--; ymax++;
1445. 	    for(i = xmin+1; i < xmax; i++) {
1446. 		mkinvpos(i, ymin, dist);
1447. 		mkinvpos(i, ymax, dist);
1448. 	    }
1449. 	}
1450. 
1451. 	/* left and right */
1452. 	for(i = ymin; i <= ymax; i++) {
1453. 	    mkinvpos(xmin, i, dist);
1454. 	    mkinvpos(xmax, i, dist);
1455. 	}
1456. 
1457. 	flush_screen(1);	/* make sure the new glyphs shows up */
1458. 	delay_output();
1459.     }
1460. 
1461.     You("are standing at the top of a stairwell leading down!");
1462.     mkstairs(u.ux, u.uy, 0, (struct mkroom *)0); /* down */
1463.     newsym(u.ux, u.uy);
1464.     vision_full_recalc = 1;	/* everything changed */
1465. }
1466. 

mkinvpos[]

1467. /* Change level topology.  Boulders in the vicinity are eliminated.
1468.  * Temporarily overrides vision in the name of a nice effect.
1469.  */
1470. STATIC_OVL void
1471. mkinvpos(x,y,dist)
1472. xchar x,y;
1473. int dist;
1474. {
1475.     struct trap *ttmp;
1476.     struct obj *otmp;
1477.     boolean make_rocks;
1478.     register struct rm *lev = &levl[x][y];
1479. 
1480.     /* clip at existing map borders if necessary */
1481.     if (!within_bounded_area(x, y, x_maze_min + 1, y_maze_min + 1,
1482. 				   x_maze_max - 1, y_maze_max - 1)) {
1483. 	/* only outermost 2 columns and/or rows may be truncated due to edge */
1484. 	if (dist < (7 - 2))
1485. 	    panic("mkinvpos: <%d,%d> (%d) off map edge!", x, y, dist);
1486. 	return;
1487.     }
1488. 
1489.     /* clear traps */
1490.     if ((ttmp = t_at(x,y)) != 0) deltrap(ttmp);
1491. 
1492.     /* clear boulders; leave some rocks for non-{moat|trap} locations */
1493.     make_rocks = (dist != 1 && dist != 4 && dist != 5) ? TRUE : FALSE;
1494.     while ((otmp = sobj_at(BOULDER, x, y)) != 0) {
1495. 	if (make_rocks) {
1496. 	    fracture_rock(otmp);
1497. 	    make_rocks = FALSE;		/* don't bother with more rocks */
1498. 	} else {
1499. 	    obj_extract_self(otmp);
1500. 	    obfree(otmp, (struct obj *)0);
1501. 	}
1502.     }
1503.     unblock_point(x,y);	/* make sure vision knows this location is open */
1504. 
1505.     /* fake out saved state */
1506.     lev->seenv = 0;
1507.     lev->doormask = 0;
1508.     if(dist < 6) lev->lit = TRUE;
1509.     lev->waslit = TRUE;
1510.     lev->horizontal = FALSE;
1511.     viz_array[y][x] = (dist < 6 ) ?
1512. 	(IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
1513. 	COULD_SEE;
1514. 
1515.     switch(dist) {
1516.     case 1: /* fire traps */
1517. 	if (is_pool(x,y)) break;
1518. 	lev->typ = ROOM;
1519. 	ttmp = maketrap(x, y, FIRE_TRAP);
1520. 	if (ttmp) ttmp->tseen = TRUE;
1521. 	break;
1522.     case 0: /* lit room locations */
1523.     case 2:
1524.     case 3:
1525.     case 6: /* unlit room locations */
1526. 	lev->typ = ROOM;
1527. 	break;
1528.     case 4: /* pools (aka a wide moat) */
1529.     case 5:
1530. 	lev->typ = MOAT;
1531. 	/* No kelp! */
1532. 	break;
1533.     default:
1534. 	impossible("mkinvpos called with dist %d", dist);
1535. 	break;
1536.     }
1537. 
1538.     /* display new value of position; could have a monster/object on it */
1539.     newsym(x,y);
1540. }
1541. 

mk_knox_portal[]

1542. /*
1543.  * The portal to Ludios is special.  The entrance can only occur within a
1544.  * vault in the main dungeon at a depth greater than 10.  The Ludios branch
1545.  * structure reflects this by having a bogus "source" dungeon:  the value
1546.  * of n_dgns (thus, Is_branchlev() will never find it).
1547.  *
1548.  * Ludios will remain isolated until the branch is corrected by this function.
1549.  */
1550. STATIC_OVL void
1551. mk_knox_portal(x, y)
1552. xchar x, y;
1553. {
1554. 	extern int n_dgns;		/* from dungeon.c */
1555. 	d_level *source;
1556. 	branch *br;
1557. 	schar u_depth;
1558. 
1559. 	br = dungeon_branch("Fort Ludios");
1560. 	if (on_level(&knox_level, &br->end1)) {
1561. 	    source = &br->end2;
1562. 	} else {
1563. 	    /* disallow Knox branch on a level with one branch already */
1564. 	    if(Is_branchlev(&u.uz))
1565. 		return;
1566. 	    source = &br->end1;
1567. 	}
1568. 
1569. 	/* Already set or 2/3 chance of deferring until a later level. */
1570. 	if (source->dnum < n_dgns || (rn2(3)
1571. #ifdef WIZARD
1572. 				      && !wizard
1573. #endif
1574. 				      )) return;
1575. 
1576. 	if (! (u.uz.dnum == oracle_level.dnum	    /* in main dungeon */
1577. 		&& !at_dgn_entrance("The Quest")    /* but not Quest's entry */
1578. 		&& (u_depth = depth(&u.uz)) > 10    /* beneath 10 */
1579. 		&& u_depth < depth(&medusa_level))) /* and above Medusa */
1580. 	    return;
1581. 
1582. 	/* Adjust source to be current level and re-insert branch. */
1583. 	*source = u.uz;
1584. 	insert_branch(br, TRUE);
1585. 
1586. #ifdef DEBUG
1587. 	pline("Made knox portal.");
1588. #endif
1589. 	place_branch(br, x, y);
1590. }
1591. 
1592. /*mklev.c*/
Advertisement