Source:NetHack 1.3d/mkshop.c

From NetHackWiki
Jump to: navigation, search

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

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

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

1.    /*	SCCS Id: @(#)mkshop.c	1.3	87/07/14
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* mkshop.c - version 1.0.3 */
4.    
5.    #ifndef QUEST
6.    #include "hack.h"
7.    #include "mkroom.h"
8.    #include "eshk.h"
9.    #define	ESHK	((struct eshk *)(&(shk->mextra[0])))
10.   extern struct monst *makemon();
11.   extern struct obj *mkobj_at();
12.   extern int nroom;
13.   extern char shtypes[];	/* = "=/+)%?!["; 9 types: 8 specialized, 1 mixed */
14.   #ifdef SPELLS
15.   schar shprobs[] = { 3,3,3,5,5,10,10,14,47 };	/* their probabilities */
16.   #else
17.   schar shprobs[] = { 3,3,5,5,10,10,14,50 };	/* their probabilities */
18.   #endif
19.   
20.   mkshop(){
21.   register struct mkroom *sroom;
22.   register int sh,sx,sy,i = -1;
23.   register char let;
24.   int roomno;
25.   register struct monst *shk;
26.   #ifdef WIZARD
27.   	/* first determine shoptype */
28.   	if(wizard){
29.   		extern char *getenv();
30.   		register char *ep = getenv("SHOPTYPE");
31.   		if(ep){
32.   			if(*ep == 'z' || *ep == 'Z'){
33.   				mkzoo(ZOO);
34.   				return;
35.   			}
36.   			if(*ep == 'm' || *ep == 'M'){
37.   				mkzoo(MORGUE);
38.   				return;
39.   			}
40.   			if(*ep == 'b' || *ep == 'B'){
41.   				mkzoo(BEEHIVE);
42.   				return;
43.   			}
44.   #ifdef NEWCLASS
45.   			if(*ep == 't' || *ep == 'T'){
46.   				mkzoo(COURT);
47.   				return;
48.   			}
49.   #endif
50.   			if(*ep == 's' || *ep == 'S'){
51.   				mkswamp();
52.   				return;
53.   			}
54.   			for(i=0; shtypes[i]; i++)
55.   				if(*ep == shtypes[i]) break;
56.   			goto gottype;
57.   		}
58.   	}
59.   gottype:
60.   #endif
61.   	for(sroom = &rooms[0], roomno = 0; ; sroom++, roomno++){
62.   		if(sroom->hx < 0) return;
63.   		if(sroom - rooms >= nroom) {
64.   			pline("rooms not closed by -1?");
65.   			return;
66.   		}
67.   		if(sroom->rtype) continue;
68.   		if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
69.   			continue;
70.   		if(
71.   #ifdef WIZARD
72.   		   (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) ||
73.   #endif
74.   			sroom->doorct == 1) break;
75.   	}
76.   
77.   	if(i < 0) {			/* shoptype not yet determined */
78.   	    register int j;
79.   
80.   	    for(j = rn2(100), i = 0; (j -= shprobs[i])>= 0; i++)
81.   		if(!shtypes[i]) break;			/* superfluous */
82.   	    if(isbig(sroom) && i + SHOPBASE == WANDSHOP)
83.   		i = GENERAL-SHOPBASE;
84.   	}
85.   	sroom->rtype = i + SHOPBASE;
86.   	let = shtypes[i];
87.   	sh = sroom->fdoor;
88.   	sx = doors[sh].x;
89.   	sy = doors[sh].y;
90.   	if(sx == sroom->lx-1) sx++; else
91.   	if(sx == sroom->hx+1) sx--; else
92.   	if(sy == sroom->ly-1) sy++; else
93.   	if(sy == sroom->hy+1) sy--; else {
94.   #ifdef WIZARD
95.   	    /* This is said to happen sometimes, but I've never seen it. */
96.   	    if(wizard) {
97.   		register int j = sroom->doorct;
98.   		extern int doorindex;
99.   
100.  		pline("Where is shopdoor?");
101.  		pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly,
102.  			sroom->hx, sroom->hy);
103.  		pline("doormax=%d doorct=%d fdoor=%d",
104.  			doorindex, sroom->doorct, sh);
105.  		while(j--) {
106.  			pline("door [%d,%d]", doors[sh].x, doors[sh].y);
107.  			sh++;
108.  		}
109.  		more();
110.  	    }
111.  #endif
112.  	    return;
113.  	}
114.  	if(!(shk = makemon(PM_SHK,sx,sy))) return;
115.  	shk->isshk = shk->mpeaceful = 1;
116.  	shk->msleep = 0;
117.  	shk->mtrapseen = ~0;	/* we know all the traps already */
118.  	ESHK->shoproom = roomno;
119.  	ESHK->shoplevel = dlevel;
120.  	ESHK->shd = doors[sh];
121.  	ESHK->shk.x = sx;
122.  	ESHK->shk.y = sy;
123.  	ESHK->robbed = 0;
124.  	ESHK->visitct = 0;
125.  	ESHK->following = 0;
126.  	shk->mgold = 1000 + 30*rnd(100);	/* initial capital */
127.  	ESHK->billct = 0;
128.  	findname(ESHK->shknam, let);
129.  	for(sx = sroom->lx; sx <= sroom->hx; sx++)
130.  	for(sy = sroom->ly; sy <= sroom->hy; sy++){
131.  		register struct monst *mtmp;
132.  		if((sx == sroom->lx && doors[sh].x == sx-1) ||
133.  		   (sx == sroom->hx && doors[sh].x == sx+1) ||
134.  		   (sy == sroom->ly && doors[sh].y == sy-1) ||
135.  		   (sy == sroom->hy && doors[sh].y == sy+1)) continue;
136.  		if(rn2(100) < dlevel && !m_at(sx,sy) &&
137.  		   (mtmp = makemon(PM_MIMIC, sx, sy))){
138.  			mtmp->mimic = 1;
139.  			mtmp->mappearance =
140.  			    (let && rn2(10) < dlevel) ? let : ']';
141.  			continue;
142.  		}
143.  		(void) mkobj_at(let, sx, sy);
144.  	}
145.  }
146.  
147.  mkzoo(type)
148.  int type;
149.  {
150.  	register struct mkroom *sroom;
151.  	register struct monst *mon;
152.  	register int sh,sx,sy,i;
153.  	int goldlim = 500 * dlevel;
154.  	int moct = 0;
155.  	struct permonst *morguemon();
156.  #ifdef NEWCLASS
157.  	struct permonst *courtmon();
158.  #endif
159.  
160.  	i = nroom;
161.  	for(sroom = &rooms[rn2(nroom)]; ; sroom++) {
162.  		if(sroom == &rooms[nroom])
163.  			sroom = &rooms[0];
164.  		if(!i-- || sroom->hx < 0)
165.  			return;
166.  		if(sroom->rtype)			continue;
167.  		if(type == MORGUE && sroom->rlit)	continue;
168.  		if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
169.  			continue;
170.  		if(sroom->doorct == 1 || !rn2(5))
171.  			break;
172.  	}
173.  	sroom->rtype = type;
174.  	sh = sroom->fdoor;
175.  	for(sx = sroom->lx; sx <= sroom->hx; sx++)
176.  	    for(sy = sroom->ly; sy <= sroom->hy; sy++){
177.  		if((sx == sroom->lx && doors[sh].x == sx-1) ||
178.  		   (sx == sroom->hx && doors[sh].x == sx+1) ||
179.  		   (sy == sroom->ly && doors[sh].y == sy-1) ||
180.  		   (sy == sroom->hy && doors[sh].y == sy+1)) continue;
181.  		mon = makemon(
182.  #ifdef NEWCLASS
183.  		   (type == COURT) ? courtmon() :
184.  #endif
185.  		   (type == MORGUE) ? morguemon() :
186.  		   (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0,
187.  		   sx, sy);
188.  		if(mon) mon->msleep = 1;
189.  		switch(type) {
190.  		case ZOO:
191.  		   i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
192.  		   if(i >= goldlim) i = 5*dlevel;
193.  		   goldlim -= i;
194.  		   mkgold((long)(10 + rn2(i)), sx, sy);
195.  		   break;
196.  		case MORGUE:
197.  		   /* Usually there is one dead body in the morgue */
198.  		   if(!moct && rn2(3)) {
199.  			mksobj_at(CORPSE, sx, sy);
200.  			moct++;
201.  		   }
202.  		   break;
203.  		case BEEHIVE:
204.  		   if(!rn2(3)) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
205.  		   break;
206.  		}
207.  	}
208.  #ifdef NEWCLASS
209.  	if(type == COURT)  {
210.  
211.  		sx = sroom->lx + (rn2(sroom->hx - sroom->lx));
212.  		sy = sroom->ly + (rn2(sroom->hy - sroom->ly));
213.  		levl[sx][sy].typ = THRONE;
214.  		levl[sx][sy].scrsym = THRONE_SYM;
215.  		mkgold((long) rn1(50 * dlevel,10), sx, sy);
216.  	}
217.  #endif
218.  
219.  }
220.  
221.  struct permonst *
222.  morguemon()
223.  {
224.  	extern struct permonst pm_ghost;
225.  	register int i = rn2(100), hd = rn2(dlevel);
226.  
227.  	if(hd > 10 && i < 10) return(PM_DEMON);
228.  	if(hd > 8 && i > 85) return(PM_VAMPIRE);
229.  	return((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE);
230.  }
231.  
232.  mkswamp()	/* Michiel Huisjes & Fred de Wilde */
233.  {
234.  	register struct mkroom *sroom;
235.  	register int sx,sy,i,eelct = 0;
236.  	extern struct permonst pm_eel;
237.  
238.  	for(i=0; i<5; i++) {		/* 5 tries */
239.  		sroom = &rooms[rn2(nroom)];
240.  		if(sroom->hx < 0 || sroom->rtype ||
241.  		   has_upstairs(sroom) || has_dnstairs(sroom))
242.  			continue;
243.  
244.  		/* satisfied; make a swamp */
245.  		sroom->rtype = SWAMP;
246.  		for(sx = sroom->lx; sx <= sroom->hx; sx++)
247.  		for(sy = sroom->ly; sy <= sroom->hy; sy++)
248.  		if((sx+sy)%2 && !o_at(sx,sy) && !t_at(sx,sy)
249.  			     && !m_at(sx,sy) && !nexttodoor(sx,sy)){
250.  			levl[sx][sy].typ = POOL;
251.  			levl[sx][sy].scrsym = POOL_SYM;
252.  			if(!eelct || !rn2(4)) {
253.  				(void) makemon(PM_EEL, sx, sy);
254.  				eelct++;
255.  			}
256.  		}
257.  	}
258.  }
259.  
260.  nexttodoor(sx,sy)
261.  register sx,sy;
262.  {
263.  	register dx,dy;
264.  	register struct rm *lev;
265.  	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++)
266.  		if((lev = &levl[sx+dx][sy+dy])->typ == DOOR ||
267.  		    lev->typ == SDOOR || lev->typ == LDOOR)
268.  			return(1);
269.  	return(0);
270.  }
271.  
272.  has_dnstairs(sroom)
273.  register struct mkroom *sroom;
274.  {
275.  	return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
276.  		   sroom->ly <= ydnstair && ydnstair <= sroom->hy);
277.  }
278.  
279.  has_upstairs(sroom)
280.  register struct mkroom *sroom;
281.  {
282.  	return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
283.  		   sroom->ly <= yupstair && yupstair <= sroom->hy);
284.  }
285.  
286.  isbig(sroom)
287.  register struct mkroom *sroom;
288.  {
289.  	register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
290.  	return( area > 20 );
291.  }
292.  
293.  dist2(x0,y0,x1,y1){
294.  	return((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1));
295.  }
296.  
297.  sq(a) int a; {
298.  	return(a*a);
299.  }
300.  #endif /* QUEST /**/
301.  
302.  #ifdef NEWCLASS
303.  struct permonst *
304.  courtmon()
305.  {
306.  	int     i = rn2(60) + rn2(3*dlevel);
307.  
308.  	if (i > 100)		return(PM_DRAGON);
309.  	else if (i > 95)	return(PM_XORN);
310.  	else if (i > 85)	return(PM_TROLL);
311.  	else if (i > 75)	return(PM_ETTIN);
312.  	else if (i > 60)	return(PM_CENTAUR);
313.  	else if (i > 45)	return(PM_ORC);
314.  	else if (i > 30)	return(PM_HOBGOBLIN);
315.  #ifdef KOPS
316.  	else			return(PM_GNOME);
317.  #else
318.  	else if (i > 15)	return(PM_GNOME);
319.  	else			return(PM_KOBOLD);
320.  #endif
321.  }
322.  #endif /* NEWCLASS /**/