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