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