Source:NetHack 3.0.0/mkroom.c

From NetHackWiki
Revision as of 04:56, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/mkroom.c moved to Source:NetHack 3.0.0/mkroom.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to mkroom.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mkroom.c#line123]], for example.

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

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

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

1.    /*	SCCS Id: @(#)mkroom.c	3.0	88/11/24
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    /*
6.     * Entry points:
7.     *	mkroom() -- make and stock a room of a given type
8.     *	nexttodoor() -- return TRUE if adjacent to a door
9.     *	has_dnstairs() -- return TRUE if given room has a down staircase
10.    *	has_upstairs() -- return TRUE if given room has an up staircase
11.    *	dist2() -- Euclidean square-of-distance function
12.    *	courtmon() -- generate a court monster
13.    */
14.   #include "hack.h"
15.   
16.   static void mkshop(), mkzoo(), mkswamp();
17.   #ifdef ORACLE
18.   static void mkdelphi();
19.   #endif
20.   #if defined(ALTARS) && defined(THEOLOGY)
21.   static void mktemple();
22.   #endif
23.   
24.   static struct permonst *morguemon();
25.   #ifdef ARMY
26.   static struct permonst *squadmon();
27.   #endif
28.   
29.   #define sq(x) ((x)*(x))
30.   
31.   static boolean
32.   isbig(sroom)
33.   register struct mkroom *sroom;
34.   {
35.   	register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
36.   	return( area > 20 );
37.   }
38.   
39.   void
40.   mkroom(roomtype)
41.   /* make and stock a room of a given type */
42.   int	roomtype;
43.   {
44.   
45.       if (roomtype >= SHOPBASE)
46.   	mkshop();	/* someday, we should be able to specify shop type */
47.       else switch(roomtype) {
48.   #ifdef THRONES
49.   	case COURT:	mkzoo(COURT); break;
50.   #endif
51.   	case ZOO:	mkzoo(ZOO); break;
52.   	case BEEHIVE:	mkzoo(BEEHIVE); break;
53.   	case MORGUE:	mkzoo(MORGUE); break;
54.   	case BARRACKS:	mkzoo(BARRACKS); break;
55.   	case SWAMP:	mkswamp(); break;
56.   #ifdef ORACLE
57.   	case DELPHI:	mkdelphi(); break;
58.   #endif
59.   #if defined(ALTARS) && defined(THEOLOGY)
60.   	case TEMPLE:	mktemple(); break;
61.   #endif
62.   	default:	impossible("Tried to make a room of type %d.", roomtype);
63.       }
64.   }
65.   
66.   static void
67.   mkshop()
68.   {
69.   	register struct mkroom *sroom;
70.   	int i = -1;
71.   #ifdef WIZARD
72.   	register char *ep;
73.   
74.   	/* first determine shoptype */
75.   	if(wizard){
76.   		ep = getenv("SHOPTYPE");
77.   		if(ep){
78.   			if(*ep == 'z' || *ep == 'Z'){
79.   				mkzoo(ZOO);
80.   				return;
81.   			}
82.   			if(*ep == 'm' || *ep == 'M'){
83.   				mkzoo(MORGUE);
84.   				return;
85.   			}
86.   			if(*ep == 'b' || *ep == 'B'){
87.   				mkzoo(BEEHIVE);
88.   				return;
89.   			}
90.   #ifdef THRONES
91.   			if(*ep == 't' || *ep == 'T'){
92.   				mkzoo(COURT);
93.   				return;
94.   			}
95.   #endif
96.   #ifdef ARMY
97.   			if(*ep == 's' || *ep == 'S'){
98.   				mkzoo(BARRACKS);
99.   				return;
100.  			}
101.  #endif /* ARMY */
102.  #if defined(ALTARS) && defined(THEOLOGY)
103.  			if(*ep == '_'){
104.  				mktemple();
105.  				return;
106.  			}
107.  #endif
108.  			if(*ep == '}'){
109.  				mkswamp();
110.  				return;
111.  			}
112.  			for(i=0; shtypes[i].name; i++)
113.  				if(*ep == shtypes[i].symb) goto gottype;
114.  			i = -1;
115.  		}
116.  	}
117.  gottype:
118.  #endif
119.  	for(sroom = &rooms[0]; ; sroom++){
120.  		if(sroom->hx < 0) return;
121.  		if(sroom - rooms >= nroom) {
122.  			pline("rooms not closed by -1?");
123.  			return;
124.  		}
125.  		if(sroom->rtype != OROOM) continue;
126.  		if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
127.  			continue;
128.  		if(
129.  #ifdef WIZARD
130.  		   (wizard && ep && sroom->doorct != 0) ||
131.  #endif
132.  			sroom->doorct == 1) break;
133.  	}
134.  
135.  	if(i < 0) {			/* shoptype not yet determined */
136.  	    register int j;
137.  
138.  	    /* pick a shop type at random */
139.  	    for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++)
140.  		if (j < 0)	break;
141.  
142.  	    /* big rooms cannot be wand or book shops,
143.  	     * - so make them general stores
144.  	     */
145.  	    if(isbig(sroom) && (shtypes[i].symb == WAND_SYM
146.  #ifdef SPELLS
147.  				|| shtypes[i].symb == SPBOOK_SYM
148.  #endif
149.  								)) i = 0;
150.  	}
151.  	sroom->rtype = SHOPBASE + i;
152.  
153.  	/* stock the room with a shopkeeper and artifacts */
154.  	stock_room(&(shtypes[i]), sroom);
155.  }
156.  
157.  static struct mkroom *
158.  pick_room()
159.  /* pick an unused room, preferably with only one door */
160.  {
161.  	register struct mkroom *sroom;
162.  	register int i = nroom;
163.  
164.  	for(sroom = &rooms[rn2(nroom)]; i--; sroom++) {
165.  		if(sroom == &rooms[nroom])
166.  			sroom = &rooms[0];
167.  		if(sroom->hx < 0)
168.  			return (struct mkroom *)0;
169.  		if(sroom->rtype != OROOM)	continue;
170.  		if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
171.  			continue;
172.  		if(sroom->doorct == 1 || !rn2(5))
173.  			return sroom;
174.  	}
175.  	return (struct mkroom *)0;
176.  }
177.  
178.  static void
179.  mkzoo(type)
180.  int type;
181.  {
182.  	register struct mkroom *sroom;
183.  	struct monst *mon;
184.  	register int sx,sy,i;
185.  	int sh, tx, ty, goldlim = 500 * dlevel;
186.  
187.  	if(!(sroom = pick_room())) return;
188.  
189.  	sroom->rtype = type;
190.  	sh = sroom->fdoor;
191.  	switch(type) {
192.  	    case COURT:
193.  		tx = somex(sroom); ty = somey(sroom); break;
194.  		/* TODO: try to ensure the enthroned monster is an M2_PRINCE */
195.  	    case BEEHIVE:
196.  		tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
197.  		ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
198.  		break;
199.  	}
200.  	for(sx = sroom->lx; sx <= sroom->hx; sx++)
201.  	    for(sy = sroom->ly; sy <= sroom->hy; sy++){
202.  		if((sx == sroom->lx && doors[sh].x == sx-1) ||
203.  		   (sx == sroom->hx && doors[sh].x == sx+1) ||
204.  		   (sy == sroom->ly && doors[sh].y == sy-1) ||
205.  		   (sy == sroom->hy && doors[sh].y == sy+1)) continue;
206.  		mon = makemon(
207.  #ifdef THRONES
208.  		    (type == COURT) ? courtmon() :
209.  #endif
210.  #ifdef ARMY
211.  		    (type == BARRACKS) ? squadmon() :
212.  #endif
213.  		    (type == MORGUE) ? morguemon() :
214.  		    (type == BEEHIVE) ?
215.  			(sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 
216.  			 &mons[PM_KILLER_BEE]) :
217.  		    (struct permonst *) 0,
218.  		   sx, sy);
219.  		if(mon) {
220.  			mon->msleep = 1;
221.  #ifdef THRONES
222.  			if (type==COURT && mon->mpeaceful) {
223.  				mon->mpeaceful = 0;
224.  				mon->malign = max(3,abs(mon->data->maligntyp));
225.  			}
226.  #endif
227.  		}
228.  		switch(type) {
229.  		    case ZOO:
230.  			i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
231.  			if(i >= goldlim) i = 5*dlevel;
232.  			goldlim -= i;
233.  			mkgold((long)(10 + rn2(i)), sx, sy);
234.  			break;
235.  		    case MORGUE:
236.  			if(!rn2(5))
237.  			    (void) mk_tt_corpse(sx, sy);
238.  			if(!rn2(10))	/* lots of treasure buried with dead */
239.  			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
240.  			break;
241.  		    case BEEHIVE:
242.  			if(!rn2(3))
243.  			    (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
244.  			break;
245.  		    case BARRACKS:
246.  			if(!rn2(20))	/* the payroll and some loot */
247.  			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
248.  			break;
249.  		}
250.  	}
251.  #ifdef THRONES
252.  	if(type == COURT)  {
253.  		levl[tx][ty].typ = THRONE;
254.  		levl[tx][ty].scrsym = THRONE_SYM;
255.  
256.  		tx = somex(sroom);
257.  		ty = somey(sroom);
258.  		mkgold((long) rn1(50 * dlevel,10), sx, sy);
259.  		(void) mksobj_at(CHEST, sx, sy);    /* the royal coffers */
260.  	}
261.  #endif
262.  
263.  }
264.  
265.  static struct permonst *
266.  morguemon()
267.  {
268.  	register int i = rn2(100), hd = rn2(dlevel);
269.  
270.  	if(hd > 10 && i < 10)
271.  		return((Inhell) ? mkclass(S_DEMON) : &mons[ndemon()]);
272.  	if(hd > 8 && i > 85)
273.  		return(mkclass(S_VAMPIRE));
274.  
275.  	return((i < 20) ? &mons[PM_GHOST]
276.  			: (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE));
277.  }
278.  
279.  static void
280.  mkswamp()	/* Michiel Huisjes & Fred de Wilde */
281.  {
282.  	register struct mkroom *sroom;
283.  	register int sx,sy,i,eelct = 0;
284.  
285.  	for(i=0; i<5; i++) {		/* 5 tries */
286.  		sroom = &rooms[rn2(nroom)];
287.  		if(sroom->hx < 0 || sroom->rtype != OROOM ||
288.  		   has_upstairs(sroom) || has_dnstairs(sroom))
289.  			continue;
290.  
291.  		/* satisfied; make a swamp */
292.  		sroom->rtype = SWAMP;
293.  		for(sx = sroom->lx; sx <= sroom->hx; sx++)
294.  		for(sy = sroom->ly; sy <= sroom->hy; sy++)
295.  		if(levl[sx][sy].omask == 0 && levl[sx][sy].gmask == 0 &&
296.  		   levl[sx][sy].mmask == 0 &&
297.  		   !t_at(sx,sy) && !nexttodoor(sx,sy)) {
298.  		    if((sx+sy)%2) {
299.  			levl[sx][sy].typ = POOL;
300.  			levl[sx][sy].scrsym = POOL_SYM;
301.  			if(!eelct || !rn2(4)) {
302.  				(void) makemon(mkclass(S_EEL), sx, sy);
303.  				eelct++;
304.  			}
305.  		    } else if(!rn2(4))	/* swamps tend to be moldy */
306.  			(void) makemon(mkclass(S_FUNGUS), sx, sy);
307.  		}
308.  	}
309.  }
310.  
311.  #ifdef ORACLE
312.  static void
313.  mkdelphi()
314.  {
315.  	register struct mkroom *sroom;
316.  	register struct monst *oracl;
317.  	int dy,xx,yy;
318.  
319.  	if(doorindex >= DOORMAX) return;
320.  	if(!(sroom = pick_room())) return;
321.  
322.  	if(!place_oracle(sroom,&dy,&xx,&yy)) return;
323.  
324.  	/* set up Oracle and environment */
325.  	if(!(oracl = makemon(&mons[PM_ORACLE],xx,yy))) return;
326.  	sroom->rtype = DELPHI;
327.  	oracl->mpeaceful = 1;
328.  
329.  	yy -= dy;
330.  	if(ACCESSIBLE(levl[xx-1][yy].typ))
331.  		(void) mkstatue(&mons[PM_FOREST_CENTAUR], xx-1, yy);
332.  	if(ACCESSIBLE(levl[xx][yy].typ))
333.  		(void) mkstatue(&mons[PM_MOUNTAIN_CENTAUR], xx, yy);
334.  	if(ACCESSIBLE(levl[xx+1][yy].typ))
335.  		(void) mkstatue(&mons[PM_PLAINS_CENTAUR], xx+1, yy);
336.  # ifdef FOUNTAINS
337.  	mkfount(0,sroom);
338.  # endif
339.  }
340.  #endif
341.  
342.  #if defined(ALTARS) && defined(THEOLOGY)
343.  void
344.  shrine_pos(sx,sy,troom)
345.  int *sx,*sy;
346.  struct mkroom *troom;
347.  {
348.  	*sx = troom->lx + ((troom->hx - troom->lx) / 2);
349.  	*sy = troom->ly + ((troom->hy - troom->ly) / 2);
350.  }
351.  
352.  static void
353.  mktemple()
354.  {
355.  	register struct mkroom *sroom;
356.  	int sx,sy;
357.  
358.  	if(!(sroom = pick_room())) return;
359.  
360.  	/* set up Priest and shrine */
361.  	sroom->rtype = TEMPLE;
362.  	shrine_pos(&sx,&sy,sroom);
363.  	/*
364.  	 * In temples, shrines are blessed altars
365.  	 * located in the center of the room
366.  	 */
367.  	levl[sx][sy].typ = ALTAR;
368.  	levl[sx][sy].scrsym = ALTAR_SYM;
369.  	levl[sx][sy].altarmask = rn2((int)A_LAW+1) | A_SHRINE;
370.  	priestini(dlevel, sx, sy, (int) levl[sx][sy].altarmask);
371.  }
372.  #endif
373.  
374.  boolean
375.  nexttodoor(sx,sy)
376.  register int sx, sy;
377.  {
378.  	register int dx, dy;
379.  	register struct rm *lev;
380.  	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
381.  		if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
382.  		    lev->typ == SDOOR)
383.  			return(TRUE);
384.  	return(FALSE);
385.  }
386.  
387.  boolean
388.  has_dnstairs(sroom)
389.  register struct mkroom *sroom;
390.  {
391.  	return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
392.  		   sroom->ly <= ydnstair && ydnstair <= sroom->hy);
393.  }
394.  
395.  boolean
396.  has_upstairs(sroom)
397.  register struct mkroom *sroom;
398.  {
399.  	return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
400.  		   sroom->ly <= yupstair && yupstair <= sroom->hy);
401.  }
402.  
403.  int
404.  dist2(x0,y0,x1,y1)
405.  int x0, y0, x1, y1;
406.  {
407.  	register int dx = x0 - x1, dy = y0 - y1;
408.  	return sq(dx) + sq(dy);
409.  }
410.  
411.  #ifdef THRONES
412.  struct permonst *
413.  courtmon()
414.  {
415.  	int     i = rn2(60) + rn2(3*dlevel);
416.  	if (i > 100)		return(mkclass(S_DRAGON));
417.  	else if (i > 95)	return(mkclass(S_GIANT));
418.  	else if (i > 85)	return(mkclass(S_TROLL));
419.  	else if (i > 75)	return(mkclass(S_CENTAUR));
420.  	else if (i > 60)	return(mkclass(S_ORC));
421.  	else if (i > 45)	return(&mons[PM_BUGBEAR]);
422.  	else if (i > 30)	return(&mons[PM_HOBGOBLIN]);
423.  	else if (i > 15)	return(mkclass(S_GNOME));
424.  	else			return(mkclass(S_KOBOLD));
425.  }
426.  #endif /* THRONES /**/
427.  
428.  #ifdef ARMY
429.  #define	    NSTYPES	(PM_CAPTAIN-PM_SOLDIER+1)
430.  
431.  struct {
432.      unsigned	pm;
433.      unsigned	prob;
434.  }   squadprob[NSTYPES] = {
435.      PM_SOLDIER, 80, PM_SERGEANT, 15, PM_LIEUTENANT, 4, PM_CAPTAIN, 1
436.  };
437.  
438.  static struct permonst *
439.  squadmon() {	    /* return soldier types. */
440.  
441.  	register struct permonst *ptr;
442.  	register int	i, cpro, sel = rnd(80+dlevel);
443.  
444.  	for(cpro = i = 0; i < NSTYPES; i++)
445.  	    if((cpro += squadprob[i].prob) > sel) {
446.  
447.  		ptr = &mons[squadprob[i].pm];
448.  		goto gotone;
449.  	    }
450.  	ptr = &mons[squadprob[rn2(NSTYPES)].pm];
451.  gotone:
452.  	if(!(ptr->geno & G_GENOD))  return(ptr);
453.  	else			    return((struct permonst *) 0);
454.  }
455.  #endif /* ARMY /* */