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