Source:NetHack 2.3e/mkshop.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to mkshop.c from the source code of NetHack 2.3e.

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)mkshop.c	2.3	87/12/12
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    /*
5.     * Entry points:
6.     *	mkroom() -- make and stock a room of a given type
7.     *	nexttodoor() -- return TRUE if adjacent to a door
8.     *	has_dnstairs() -- return TRUE if given room has a down staircase
9.     *	has_upstairs() -- return TRUE if given room has an up staircase
10.    *	dist2() -- Euclidean square-of-distance function
11.    *	courtmon() -- generate a court monster
12.    *
13.    * (note: this module should become mkroom.c in the next major release)
14.    */
15.   #ifndef QUEST
16.   #include "hack.h"
17.   #include "mkroom.h"
18.   extern struct monst *makemon();
19.   extern struct permonst pm_soldier;
20.   extern struct obj *mkobj_at(), *mksobj_at();
21.   extern void stock_room();
22.   extern int nroom;
23.   
24.   static boolean
25.   isbig(sroom)
26.   register struct mkroom *sroom;
27.   {
28.   	register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
29.   	return( area > 20 );
30.   }
31.   
32.   void
33.   mkroom(roomtype)
34.   /* make and stock a room of a given type */
35.   int	roomtype;
36.   {
37.       void mkshop(), mkzoo(), mkswamp();
38.   
39.       if (roomtype >= SHOPBASE)
40.   	mkshop();	/* someday, we should be able to specify shop type */
41.       else switch(roomtype)
42.       {
43.       case COURT: mkzoo(COURT); break;
44.       case ZOO: mkzoo(ZOO); break;
45.       case BEEHIVE: mkzoo(BEEHIVE); break;
46.       case MORGUE: mkzoo(MORGUE); break;
47.       case BARRACKS: mkzoo(BARRACKS); break;
48.       case SWAMP: mkswamp(); break;
49.       default:	impossible("Tried to make a room of type %d.", roomtype);
50.       }
51.   }
52.   
53.   static void
54.   mkshop(){
55.   register struct mkroom *sroom;
56.   int roomno, i = -1;
57.   #ifdef WIZARD
58.   extern char *getenv();
59.   
60.   	/* first determine shoptype */
61.   	if(wizard){
62.   		register char *ep = getenv("SHOPTYPE");
63.   		if(ep){
64.   			if(*ep == 'z' || *ep == 'Z'){
65.   				mkzoo(ZOO);
66.   				return;
67.   			}
68.   			if(*ep == 'm' || *ep == 'M'){
69.   				mkzoo(MORGUE);
70.   				return;
71.   			}
72.   			if(*ep == 'b' || *ep == 'B'){
73.   				mkzoo(BEEHIVE);
74.   				return;
75.   			}
76.   #ifdef NEWCLASS
77.   			if(*ep == 't' || *ep == 'T'){
78.   				mkzoo(COURT);
79.   				return;
80.   			}
81.   #endif
82.   #ifdef SAC
83.   			if(*ep == '3'){
84.   				mkzoo(BARRACKS);
85.   				return;
86.   			}
87.   #endif /* SAC */
88.   			if(*ep == 's' || *ep == 'S'){
89.   				mkswamp();
90.   				return;
91.   			}
92.   			for(i=0; shtypes[i].name; i++)
93.   				if(*ep == shtypes[i].symb) goto gottype;
94.   			i = -1;
95.   		}
96.   	}
97.   gottype:
98.   #endif
99.   	for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){
100.  		if(sroom->hx < 0) return;
101.  		if(sroom - rooms >= nroom) {
102.  			pline("rooms not closed by -1?");
103.  			return;
104.  		}
105.  		if(sroom->rtype != OROOM) continue;
106.  		if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
107.  			continue;
108.  		if(
109.  #ifdef WIZARD
110.  		   (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) ||
111.  #endif
112.  			sroom->doorct == 1) break;
113.  	}
114.  
115.  	if(i < 0) {			/* shoptype not yet determined */
116.  	    register int j;
117.  
118.  	    /* pick a shop type at random */
119.  	    for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++)
120.  		if (j < 0)	break;
121.  
122.  	    /* big rooms cannot be wand or book shops,
123.  	     * - so make them general stores
124.  	     */
125.  	    if(isbig(sroom) && (shtypes[i].symb == WAND_SYM
126.  #ifdef SPELLS
127.  				|| shtypes[i].symb == SPBOOK_SYM
128.  #endif
129.  								)) i = 0;
130.  	}
131.  	sroom->rtype = SHOPBASE + i;
132.  
133.  	/* stock the room with a shopkeeper and artifacts */
134.  	stock_room(&(shtypes[i]), sroom);
135.  }
136.  
137.  static void
138.  mkzoo(type)
139.  int type;
140.  {
141.  	register struct mkroom *sroom;
142.  	register struct monst *mon;
143.  	register int sh,sx,sy,i;
144.  	int goldlim = 500 * dlevel;
145.  	int moct = 0;
146.  	struct permonst *morguemon();
147.  #ifdef NEWCLASS
148.  	struct permonst *courtmon();
149.  #endif
150.  
151.  	i = nroom;
152.  	for(sroom = &rooms[rn2(nroom)]; ; sroom++) {
153.  		if(sroom == &rooms[nroom])
154.  			sroom = &rooms[0];
155.  		if(!i-- || sroom->hx < 0)
156.  			return;
157.  		if(sroom->rtype != OROOM)	continue;
158.  		if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
159.  			continue;
160.  		if(sroom->doorct == 1 || !rn2(5))
161.  			break;
162.  	}
163.  	sroom->rtype = type;
164.  	sh = sroom->fdoor;
165.  	for(sx = sroom->lx; sx <= sroom->hx; sx++)
166.  	    for(sy = sroom->ly; sy <= sroom->hy; sy++){
167.  		if((sx == sroom->lx && doors[sh].x == sx-1) ||
168.  		   (sx == sroom->hx && doors[sh].x == sx+1) ||
169.  		   (sy == sroom->ly && doors[sh].y == sy-1) ||
170.  		   (sy == sroom->hy && doors[sh].y == sy+1)) continue;
171.  		mon = makemon(
172.  #ifdef NEWCLASS
173.  		   (type == COURT) ? courtmon() :
174.  #endif
175.  #ifdef SAC
176.  		   (type == BARRACKS) ? PM_SOLDIER :
177.  #endif
178.  		   (type == MORGUE) ? morguemon() :
179.  		   (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0,
180.  		   sx, sy);
181.  		if(mon) mon->msleep = 1;
182.  		switch(type) {
183.  		case ZOO:
184.  		   i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
185.  		   if(i >= goldlim) i = 5*dlevel;
186.  		   goldlim -= i;
187.  		   mkgold((long)(10 + rn2(i)), sx, sy);
188.  		   break;
189.  		case MORGUE:
190.  		   /* Usually there is one dead body in the morgue */
191.  		   if(!moct && rn2(3)) {
192.  			mksobj_at(CORPSE, sx, sy);
193.  			moct++;
194.  		   }
195.  		   break;
196.  		case BEEHIVE:
197.  		   if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
198.  		   break;
199.  		}
200.  	}
201.  #ifdef NEWCLASS
202.  	if(type == COURT)  {
203.  
204.  		sx = sroom->lx + (rn2(sroom->hx - sroom->lx));
205.  		sy = sroom->ly + (rn2(sroom->hy - sroom->ly));
206.  		levl[sx][sy].typ = THRONE;
207.  		levl[sx][sy].scrsym = THRONE_SYM;
208.  		mkgold((long) rn1(50 * dlevel,10), sx, sy);
209.  	}
210.  #endif
211.  
212.  }
213.  
214.  static struct permonst *
215.  morguemon()
216.  {
217.  	extern struct permonst pm_ghost;
218.  	register int i = rn2(100), hd = rn2(dlevel);
219.  
220.  	if(hd > 10 && i < 10) return(PM_DEMON);
221.  	if(hd > 8 && i > 85) return(PM_VAMPIRE);
222.  	return((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE);
223.  }
224.  
225.  static void
226.  mkswamp()	/* Michiel Huisjes & Fred de Wilde */
227.  {
228.  	register struct mkroom *sroom;
229.  	register int sx,sy,i,eelct = 0;
230.  	extern struct permonst pm_eel;
231.  
232.  	for(i=0; i<5; i++) {		/* 5 tries */
233.  		sroom = &rooms[rn2(nroom)];
234.  		if(sroom->hx < 0 || sroom->rtype != OROOM ||
235.  		   has_upstairs(sroom) || has_dnstairs(sroom))
236.  			continue;
237.  
238.  		/* satisfied; make a swamp */
239.  		sroom->rtype = SWAMP;
240.  		for(sx = sroom->lx; sx <= sroom->hx; sx++)
241.  		for(sy = sroom->ly; sy <= sroom->hy; sy++)
242.  		if((sx+sy)%2 && !o_at(sx,sy) && !t_at(sx,sy)
243.  			     && !m_at(sx,sy) && !nexttodoor(sx,sy)){
244.  			levl[sx][sy].typ = POOL;
245.  			levl[sx][sy].scrsym = POOL_SYM;
246.  			if(!eelct || !rn2(4)) {
247.  				(void) makemon(PM_EEL, sx, sy);
248.  				eelct++;
249.  			}
250.  		}
251.  	}
252.  }
253.  
254.  boolean
255.  nexttodoor(sx,sy)
256.  register sx,sy;
257.  {
258.  	register dx,dy;
259.  	register struct rm *lev;
260.  	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
261.  		if((lev = &levl[sx+dx][sy+dy])->typ == DOOR ||
262.  		    lev->typ == SDOOR || lev->typ == LDOOR)
263.  			return(TRUE);
264.  	return(FALSE);
265.  }
266.  
267.  boolean
268.  has_dnstairs(sroom)
269.  register struct mkroom *sroom;
270.  {
271.  	return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
272.  		   sroom->ly <= ydnstair && ydnstair <= sroom->hy);
273.  }
274.  
275.  boolean
276.  has_upstairs(sroom)
277.  register struct mkroom *sroom;
278.  {
279.  	return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
280.  		   sroom->ly <= yupstair && yupstair <= sroom->hy);
281.  }
282.  
283.  int
284.  dist2(x0,y0,x1,y1){
285.  	return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
286.  }
287.  
288.  static int
289.  sq(a) int a; {
290.  	return(a*a);
291.  }
292.  #endif /* QUEST /**/
293.  
294.  #ifdef NEWCLASS
295.  struct permonst *
296.  courtmon()
297.  {
298.  	int     i = rn2(60) + rn2(3*dlevel);
299.  
300.  	if (i > 100)		return(PM_DRAGON);
301.  	else if (i > 95)	return(PM_XORN);
302.  	else if (i > 85)	return(PM_TROLL);
303.  	else if (i > 75)	return(PM_ETTIN);
304.  	else if (i > 60)	return(PM_CENTAUR);
305.  	else if (i > 45)	return(PM_ORC);
306.  	else if (i > 30)	return(PM_HOBGOBLIN);
307.  #ifdef KOPS
308.  	else			return(PM_GNOME);
309.  #else
310.  	else if (i > 15)	return(PM_GNOME);
311.  	else			return(PM_KOBOLD);
312.  #endif
313.  }
314.  #endif /* NEWCLASS /**/