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