hack.mkshop.c revision 1.10 1 1.10 dholland /* $NetBSD: hack.mkshop.c,v 1.10 2009/08/12 07:28:41 dholland Exp $ */
2 1.5 christos
3 1.3 mycroft /*
4 1.8 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 1.8 jsm * Amsterdam
6 1.8 jsm * All rights reserved.
7 1.8 jsm *
8 1.8 jsm * Redistribution and use in source and binary forms, with or without
9 1.8 jsm * modification, are permitted provided that the following conditions are
10 1.8 jsm * met:
11 1.8 jsm *
12 1.8 jsm * - Redistributions of source code must retain the above copyright notice,
13 1.8 jsm * this list of conditions and the following disclaimer.
14 1.8 jsm *
15 1.8 jsm * - Redistributions in binary form must reproduce the above copyright
16 1.8 jsm * notice, this list of conditions and the following disclaimer in the
17 1.8 jsm * documentation and/or other materials provided with the distribution.
18 1.8 jsm *
19 1.8 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en
20 1.8 jsm * Informatica, nor the names of its contributors may be used to endorse or
21 1.8 jsm * promote products derived from this software without specific prior
22 1.8 jsm * written permission.
23 1.8 jsm *
24 1.8 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 1.8 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 1.8 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 1.8 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 1.8 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 1.8 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 1.8 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 1.8 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 1.8 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 1.8 jsm */
36 1.8 jsm
37 1.8 jsm /*
38 1.8 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org>
39 1.8 jsm * All rights reserved.
40 1.8 jsm *
41 1.8 jsm * Redistribution and use in source and binary forms, with or without
42 1.8 jsm * modification, are permitted provided that the following conditions
43 1.8 jsm * are met:
44 1.8 jsm * 1. Redistributions of source code must retain the above copyright
45 1.8 jsm * notice, this list of conditions and the following disclaimer.
46 1.8 jsm * 2. Redistributions in binary form must reproduce the above copyright
47 1.8 jsm * notice, this list of conditions and the following disclaimer in the
48 1.8 jsm * documentation and/or other materials provided with the distribution.
49 1.8 jsm * 3. The name of the author may not be used to endorse or promote products
50 1.8 jsm * derived from this software without specific prior written permission.
51 1.8 jsm *
52 1.8 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 1.8 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 1.8 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 1.8 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 1.8 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 1.8 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 1.8 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 1.8 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 1.3 mycroft */
63 1.3 mycroft
64 1.5 christos #include <sys/cdefs.h>
65 1.3 mycroft #ifndef lint
66 1.10 dholland __RCSID("$NetBSD: hack.mkshop.c,v 1.10 2009/08/12 07:28:41 dholland Exp $");
67 1.5 christos #endif /* not lint */
68 1.1 cgd
69 1.2 mycroft #include <stdlib.h>
70 1.1 cgd #ifndef QUEST
71 1.1 cgd #include "hack.h"
72 1.5 christos #include "extern.h"
73 1.1 cgd #include "def.mkroom.h"
74 1.1 cgd #include "def.eshk.h"
75 1.10 dholland
76 1.1 cgd #define ESHK ((struct eshk *)(&(shk->mextra[0])))
77 1.10 dholland
78 1.10 dholland /* their probabilities */
79 1.10 dholland static const schar shprobs[] = {3, 3, 5, 5, 10, 10, 14, 50};
80 1.10 dholland
81 1.10 dholland static const struct permonst *morguemon(void);
82 1.10 dholland static int nexttodoor(int, int);
83 1.10 dholland static int has_dnstairs(struct mkroom *);
84 1.10 dholland static int has_upstairs(struct mkroom *);
85 1.10 dholland static int isbig(struct mkroom *);
86 1.10 dholland static int dist2(int, int, int, int);
87 1.10 dholland static int sq(int);
88 1.5 christos
89 1.5 christos void
90 1.9 dholland mkshop(void)
91 1.5 christos {
92 1.5 christos struct mkroom *sroom;
93 1.5 christos int sh, sx, sy, i = -1;
94 1.5 christos char let;
95 1.5 christos int roomno;
96 1.5 christos struct monst *shk;
97 1.1 cgd #ifdef WIZARD
98 1.1 cgd /* first determine shoptype */
99 1.5 christos if (wizard) {
100 1.5 christos char *ep = getenv("SHOPTYPE");
101 1.5 christos if (ep) {
102 1.5 christos if (*ep == 'z' || *ep == 'Z') {
103 1.1 cgd mkzoo(ZOO);
104 1.1 cgd return;
105 1.1 cgd }
106 1.5 christos if (*ep == 'm' || *ep == 'M') {
107 1.1 cgd mkzoo(MORGUE);
108 1.1 cgd return;
109 1.1 cgd }
110 1.5 christos if (*ep == 'b' || *ep == 'B') {
111 1.1 cgd mkzoo(BEEHIVE);
112 1.1 cgd return;
113 1.1 cgd }
114 1.5 christos if (*ep == 's' || *ep == 'S') {
115 1.1 cgd mkswamp();
116 1.1 cgd return;
117 1.1 cgd }
118 1.5 christos for (i = 0; shtypes[i]; i++)
119 1.5 christos if (*ep == shtypes[i])
120 1.5 christos break;
121 1.1 cgd goto gottype;
122 1.1 cgd }
123 1.1 cgd }
124 1.1 cgd gottype:
125 1.5 christos #endif /* WIZARD */
126 1.5 christos for (sroom = &rooms[0], roomno = 0;; sroom++, roomno++) {
127 1.5 christos if (sroom->hx < 0)
128 1.5 christos return;
129 1.5 christos if (sroom - rooms >= nroom) {
130 1.1 cgd pline("rooms not closed by -1?");
131 1.1 cgd return;
132 1.1 cgd }
133 1.5 christos if (sroom->rtype)
134 1.5 christos continue;
135 1.5 christos if (!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
136 1.1 cgd continue;
137 1.5 christos if (
138 1.1 cgd #ifdef WIZARD
139 1.5 christos (wizard && getenv("SHOPTYPE") && sroom->doorct != 0) ||
140 1.5 christos #endif /* WIZARD */
141 1.7 chuck sroom->doorct == 1)
142 1.5 christos break;
143 1.1 cgd }
144 1.1 cgd
145 1.5 christos if (i < 0) { /* shoptype not yet determined */
146 1.5 christos int j;
147 1.1 cgd
148 1.5 christos for (j = rn2(100), i = 0; (j -= shprobs[i]) >= 0; i++)
149 1.5 christos if (!shtypes[i])
150 1.5 christos break; /* superfluous */
151 1.5 christos if (isbig(sroom) && i + SHOPBASE == WANDSHOP)
152 1.5 christos i = GENERAL - SHOPBASE;
153 1.1 cgd }
154 1.1 cgd sroom->rtype = i + SHOPBASE;
155 1.1 cgd let = shtypes[i];
156 1.1 cgd sh = sroom->fdoor;
157 1.1 cgd sx = doors[sh].x;
158 1.1 cgd sy = doors[sh].y;
159 1.5 christos if (sx == sroom->lx - 1)
160 1.5 christos sx++;
161 1.5 christos else if (sx == sroom->hx + 1)
162 1.5 christos sx--;
163 1.5 christos else if (sy == sroom->ly - 1)
164 1.5 christos sy++;
165 1.5 christos else if (sy == sroom->hy + 1)
166 1.5 christos sy--;
167 1.5 christos else {
168 1.1 cgd #ifdef WIZARD
169 1.5 christos /* This is said to happen sometimes, but I've never seen it. */
170 1.5 christos if (wizard) {
171 1.5 christos int j = sroom->doorct;
172 1.5 christos
173 1.5 christos pline("Where is shopdoor?");
174 1.5 christos pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly,
175 1.5 christos sroom->hx, sroom->hy);
176 1.5 christos pline("doormax=%d doorct=%d fdoor=%d",
177 1.5 christos doorindex, sroom->doorct, sh);
178 1.5 christos while (j--) {
179 1.5 christos pline("door [%d,%d]", doors[sh].x, doors[sh].y);
180 1.5 christos sh++;
181 1.5 christos }
182 1.5 christos more();
183 1.1 cgd }
184 1.5 christos #endif /* WIZARD */
185 1.5 christos return;
186 1.1 cgd }
187 1.5 christos if (!(shk = makemon(PM_SHK, sx, sy)))
188 1.5 christos return;
189 1.1 cgd shk->isshk = shk->mpeaceful = 1;
190 1.1 cgd shk->msleep = 0;
191 1.1 cgd shk->mtrapseen = ~0; /* we know all the traps already */
192 1.1 cgd ESHK->shoproom = roomno;
193 1.1 cgd ESHK->shoplevel = dlevel;
194 1.1 cgd ESHK->shd = doors[sh];
195 1.1 cgd ESHK->shk.x = sx;
196 1.1 cgd ESHK->shk.y = sy;
197 1.1 cgd ESHK->robbed = 0;
198 1.1 cgd ESHK->visitct = 0;
199 1.1 cgd ESHK->following = 0;
200 1.5 christos shk->mgold = 1000 + 30 * rnd(100); /* initial capital */
201 1.1 cgd ESHK->billct = 0;
202 1.1 cgd findname(ESHK->shknam, let);
203 1.5 christos for (sx = sroom->lx; sx <= sroom->hx; sx++)
204 1.5 christos for (sy = sroom->ly; sy <= sroom->hy; sy++) {
205 1.5 christos struct monst *mtmp;
206 1.5 christos if ((sx == sroom->lx && doors[sh].x == sx - 1) ||
207 1.5 christos (sx == sroom->hx && doors[sh].x == sx + 1) ||
208 1.5 christos (sy == sroom->ly && doors[sh].y == sy - 1) ||
209 1.5 christos (sy == sroom->hy && doors[sh].y == sy + 1))
210 1.5 christos continue;
211 1.5 christos if (rn2(100) < dlevel && !m_at(sx, sy) &&
212 1.5 christos (mtmp = makemon(PM_MIMIC, sx, sy))) {
213 1.5 christos mtmp->mimic = 1;
214 1.5 christos mtmp->mappearance =
215 1.5 christos (let && rn2(10) < dlevel) ? let : ']';
216 1.5 christos continue;
217 1.5 christos }
218 1.5 christos (void) mkobj_at(let, sx, sy);
219 1.1 cgd }
220 1.1 cgd }
221 1.1 cgd
222 1.5 christos void
223 1.9 dholland mkzoo(int type)
224 1.1 cgd {
225 1.5 christos struct mkroom *sroom;
226 1.5 christos struct monst *mon;
227 1.5 christos int sh, sx, sy, i;
228 1.5 christos int goldlim = 500 * dlevel;
229 1.5 christos int moct = 0;
230 1.1 cgd
231 1.1 cgd i = nroom;
232 1.5 christos for (sroom = &rooms[rn2(nroom)];; sroom++) {
233 1.5 christos if (sroom == &rooms[nroom])
234 1.1 cgd sroom = &rooms[0];
235 1.5 christos if (!i-- || sroom->hx < 0)
236 1.1 cgd return;
237 1.5 christos if (sroom->rtype)
238 1.1 cgd continue;
239 1.5 christos if (type == MORGUE && sroom->rlit)
240 1.1 cgd continue;
241 1.5 christos if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
242 1.1 cgd continue;
243 1.5 christos if (sroom->doorct == 1 || !rn2(5))
244 1.1 cgd break;
245 1.1 cgd }
246 1.1 cgd sroom->rtype = type;
247 1.1 cgd sh = sroom->fdoor;
248 1.5 christos for (sx = sroom->lx; sx <= sroom->hx; sx++)
249 1.5 christos for (sy = sroom->ly; sy <= sroom->hy; sy++) {
250 1.5 christos if ((sx == sroom->lx && doors[sh].x == sx - 1) ||
251 1.5 christos (sx == sroom->hx && doors[sh].x == sx + 1) ||
252 1.5 christos (sy == sroom->ly && doors[sh].y == sy - 1) ||
253 1.5 christos (sy == sroom->hy && doors[sh].y == sy + 1))
254 1.5 christos continue;
255 1.5 christos mon = makemon(
256 1.5 christos (type == MORGUE) ? morguemon() :
257 1.5 christos (type == BEEHIVE) ? PM_KILLER_BEE : (struct permonst *) 0,
258 1.5 christos sx, sy);
259 1.5 christos if (mon)
260 1.5 christos mon->msleep = 1;
261 1.5 christos switch (type) {
262 1.5 christos case ZOO:
263 1.5 christos i = sq(dist2(sx, sy, doors[sh].x, doors[sh].y));
264 1.5 christos if (i >= goldlim)
265 1.5 christos i = 5 * dlevel;
266 1.5 christos goldlim -= i;
267 1.5 christos mkgold((long) (10 + rn2(i)), sx, sy);
268 1.5 christos break;
269 1.5 christos case MORGUE:
270 1.5 christos /*
271 1.5 christos * Usually there is one dead body in the
272 1.5 christos * morgue
273 1.5 christos */
274 1.5 christos if (!moct && rn2(3)) {
275 1.5 christos mksobj_at(CORPSE, sx, sy);
276 1.5 christos moct++;
277 1.5 christos }
278 1.5 christos break;
279 1.5 christos case BEEHIVE:
280 1.5 christos if (!rn2(3))
281 1.5 christos mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
282 1.5 christos break;
283 1.5 christos }
284 1.1 cgd }
285 1.1 cgd }
286 1.1 cgd
287 1.10 dholland static const struct permonst *
288 1.9 dholland morguemon(void)
289 1.1 cgd {
290 1.5 christos int i = rn2(100), hd = rn2(dlevel);
291 1.1 cgd
292 1.5 christos if (hd > 10 && i < 10)
293 1.5 christos return (PM_DEMON);
294 1.5 christos if (hd > 8 && i > 85)
295 1.5 christos return (PM_VAMPIRE);
296 1.5 christos return ((i < 40) ? PM_GHOST : (i < 60) ? PM_WRAITH : PM_ZOMBIE);
297 1.1 cgd }
298 1.1 cgd
299 1.5 christos void
300 1.9 dholland mkswamp(void)
301 1.5 christos { /* Michiel Huisjes & Fred de Wilde */
302 1.5 christos struct mkroom *sroom;
303 1.5 christos int sx, sy, i, eelct = 0;
304 1.1 cgd
305 1.5 christos for (i = 0; i < 5; i++) { /* 5 tries */
306 1.1 cgd sroom = &rooms[rn2(nroom)];
307 1.5 christos if (sroom->hx < 0 || sroom->rtype ||
308 1.5 christos has_upstairs(sroom) || has_dnstairs(sroom))
309 1.1 cgd continue;
310 1.1 cgd
311 1.1 cgd /* satisfied; make a swamp */
312 1.1 cgd sroom->rtype = SWAMP;
313 1.5 christos for (sx = sroom->lx; sx <= sroom->hx; sx++)
314 1.5 christos for (sy = sroom->ly; sy <= sroom->hy; sy++)
315 1.5 christos if ((sx + sy) % 2 && !o_at(sx, sy) && !t_at(sx, sy)
316 1.5 christos && !m_at(sx, sy) && !nexttodoor(sx, sy)) {
317 1.5 christos levl[sx][sy].typ = POOL;
318 1.5 christos levl[sx][sy].scrsym = POOL_SYM;
319 1.5 christos if (!eelct || !rn2(4)) {
320 1.5 christos (void) makemon(PM_EEL, sx, sy);
321 1.5 christos eelct++;
322 1.5 christos }
323 1.5 christos }
324 1.1 cgd }
325 1.1 cgd }
326 1.1 cgd
327 1.10 dholland static int
328 1.9 dholland nexttodoor(int sx, int sy)
329 1.1 cgd {
330 1.5 christos int dx, dy;
331 1.5 christos struct rm *lev;
332 1.5 christos for (dx = -1; dx <= 1; dx++)
333 1.5 christos for (dy = -1; dy <= 1; dy++)
334 1.5 christos if ((lev = &levl[sx + dx][sy + dy])->typ == DOOR ||
335 1.5 christos lev->typ == SDOOR || lev->typ == LDOOR)
336 1.5 christos return (1);
337 1.5 christos return (0);
338 1.1 cgd }
339 1.1 cgd
340 1.10 dholland static int
341 1.9 dholland has_dnstairs(struct mkroom *sroom)
342 1.1 cgd {
343 1.5 christos return (sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
344 1.5 christos sroom->ly <= ydnstair && ydnstair <= sroom->hy);
345 1.1 cgd }
346 1.1 cgd
347 1.10 dholland static int
348 1.9 dholland has_upstairs(struct mkroom *sroom)
349 1.1 cgd {
350 1.5 christos return (sroom->lx <= xupstair && xupstair <= sroom->hx &&
351 1.5 christos sroom->ly <= yupstair && yupstair <= sroom->hy);
352 1.1 cgd }
353 1.1 cgd
354 1.10 dholland static int
355 1.9 dholland isbig(struct mkroom *sroom)
356 1.1 cgd {
357 1.5 christos int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
358 1.5 christos return (area > 20);
359 1.1 cgd }
360 1.1 cgd
361 1.10 dholland static int
362 1.9 dholland dist2(int x0, int y0, int x1, int y1)
363 1.5 christos {
364 1.5 christos return ((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
365 1.1 cgd }
366 1.1 cgd
367 1.10 dholland static int
368 1.9 dholland sq(int a)
369 1.5 christos {
370 1.5 christos return (a * a);
371 1.1 cgd }
372 1.5 christos #endif /* QUEST */
373