]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.vault.c
Refer to 'O' rather than 'o' as command to set options. Bug reported
[bsdgames-darwin.git] / hack / hack.vault.c
1 /* $NetBSD: hack.vault.c,v 1.6 2003/04/02 18:36:41 jsm Exp $ */
2
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
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.
18 *
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.
23 *
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.
35 */
36
37 /*
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
40 *
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.
51 *
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.
62 */
63
64 #include <sys/cdefs.h>
65 #ifndef lint
66 __RCSID("$NetBSD: hack.vault.c,v 1.6 2003/04/02 18:36:41 jsm Exp $");
67 #endif /* not lint */
68
69 #include "hack.h"
70 #include "extern.h"
71 #ifdef QUEST
72 void
73 setgd( /* mtmp */ )
74 { /* struct monst *mtmp; */
75 }
76 int
77 gd_move() {
78 return (2);
79 }
80 void
81 gddead()
82 {
83 }
84 void
85 replgd(mtmp, mtmp2)
86 struct monst *mtmp, *mtmp2;
87 {
88 }
89 void
90 invault()
91 {
92 }
93
94 #else
95
96
97 #include "def.mkroom.h"
98 #define FCSIZ (ROWNO+COLNO)
99 struct fakecorridor {
100 xchar fx, fy, ftyp;
101 };
102
103 struct egd {
104 int fcbeg, fcend; /* fcend: first unused pos */
105 xchar gdx, gdy; /* goal of guard's walk */
106 unsigned gddone:1;
107 struct fakecorridor fakecorr[FCSIZ];
108 };
109
110 static const struct permonst pm_guard =
111 {"guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd)};
112
113 static struct monst *guard;
114 static int gdlevel;
115 #define EGD ((struct egd *)(&(guard->mextra[0])))
116
117 static void restfakecorr __P((void));
118 static int goldincorridor __P((void));
119
120 static void
121 restfakecorr()
122 {
123 int fcx, fcy, fcbeg;
124 struct rm *crm;
125
126 while ((fcbeg = EGD->fcbeg) < EGD->fcend) {
127 fcx = EGD->fakecorr[fcbeg].fx;
128 fcy = EGD->fakecorr[fcbeg].fy;
129 if ((u.ux == fcx && u.uy == fcy) || cansee(fcx, fcy) ||
130 m_at(fcx, fcy))
131 return;
132 crm = &levl[fcx][fcy];
133 crm->typ = EGD->fakecorr[fcbeg].ftyp;
134 if (!crm->typ)
135 crm->seen = 0;
136 newsym(fcx, fcy);
137 EGD->fcbeg++;
138 }
139 /* it seems he left the corridor - let the guard disappear */
140 mondead(guard);
141 guard = 0;
142 }
143
144 static int
145 goldincorridor()
146 {
147 int fci;
148
149 for (fci = EGD->fcbeg; fci < EGD->fcend; fci++)
150 if (g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
151 return (1);
152 return (0);
153 }
154
155 void
156 setgd()
157 {
158 struct monst *mtmp;
159 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
160 if (mtmp->isgd) {
161 guard = mtmp;
162 gdlevel = dlevel;
163 return;
164 }
165 guard = 0;
166 }
167
168 void
169 invault()
170 {
171 int tmp = inroom(u.ux, u.uy);
172 if (tmp < 0 || rooms[tmp].rtype != VAULT) {
173 u.uinvault = 0;
174 return;
175 }
176 if (++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
177 char buf[BUFSZ];
178 int x, y, dd, gx, gy;
179
180 /* first find the goal for the guard */
181 for (dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
182 for (y = u.uy - dd; y <= u.uy + dd; y++) {
183 if (y < 0 || y > ROWNO - 1)
184 continue;
185 for (x = u.ux - dd; x <= u.ux + dd; x++) {
186 if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
187 x = u.ux + dd;
188 if (x < 0 || x > COLNO - 1)
189 continue;
190 if (levl[x][y].typ == CORR)
191 goto fnd;
192 }
193 }
194 }
195 impossible("Not a single corridor on this level??");
196 tele();
197 return;
198 fnd:
199 gx = x;
200 gy = y;
201
202 /* next find a good place for a door in the wall */
203 x = u.ux;
204 y = u.uy;
205 while (levl[x][y].typ == ROOM) {
206 int dx, dy;
207
208 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
209 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
210 if (abs(gx - x) >= abs(gy - y))
211 x += dx;
212 else
213 y += dy;
214 }
215
216 /* make something interesting happen */
217 if (!(guard = makemon(&pm_guard, x, y)))
218 return;
219 guard->isgd = guard->mpeaceful = 1;
220 EGD->gddone = 0;
221 gdlevel = dlevel;
222 if (!cansee(guard->mx, guard->my)) {
223 mondead(guard);
224 guard = 0;
225 return;
226 }
227 pline("Suddenly one of the Vault's guards enters!");
228 pmon(guard);
229 do {
230 pline("\"Hello stranger, who are you?\" - ");
231 getlin(buf);
232 } while (!letter(buf[0]));
233
234 if (!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
235 pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
236 mondead(guard);
237 guard = 0;
238 return;
239 }
240 clrlin();
241 pline("\"I don't know you.\"");
242 if (!u.ugold)
243 pline("\"Please follow me.\"");
244 else {
245 pline("\"Most likely all that gold was stolen from this vault.\"");
246 pline("\"Please drop your gold (say d$ ) and follow me.\"");
247 }
248 EGD->gdx = gx;
249 EGD->gdy = gy;
250 EGD->fcbeg = 0;
251 EGD->fakecorr[0].fx = x;
252 EGD->fakecorr[0].fy = y;
253 EGD->fakecorr[0].ftyp = levl[x][y].typ;
254 levl[x][y].typ = DOOR;
255 EGD->fcend = 1;
256 }
257 }
258
259 int
260 gd_move()
261 {
262 int x, y, dx, dy, gx, gy, nx, ny, typ;
263 struct fakecorridor *fcp;
264 struct rm *crm;
265 if (!guard || gdlevel != dlevel) {
266 impossible("Where is the guard?");
267 return (2); /* died */
268 }
269 if (u.ugold || goldincorridor())
270 return (0); /* didnt move */
271 if (dist(guard->mx, guard->my) > 1 || EGD->gddone) {
272 restfakecorr();
273 return (0); /* didnt move */
274 }
275 x = guard->mx;
276 y = guard->my;
277 /* look around (hor & vert only) for accessible places */
278 for (nx = x - 1; nx <= x + 1; nx++)
279 for (ny = y - 1; ny <= y + 1; ny++) {
280 if (nx == x || ny == y)
281 if (nx != x || ny != y)
282 if (isok(nx, ny))
283 if (!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
284 int i;
285 for (i = EGD->fcbeg; i < EGD->fcend; i++)
286 if (EGD->fakecorr[i].fx == nx &&
287 EGD->fakecorr[i].fy == ny)
288 goto nextnxy;
289 if ((i = inroom(nx, ny)) >= 0 && rooms[i].rtype == VAULT)
290 goto nextnxy;
291 /*
292 * seems we found a
293 * good place to
294 * leave him alone
295 */
296 EGD->gddone = 1;
297 if (ACCESSIBLE(typ))
298 goto newpos;
299 crm->typ = (typ == SCORR) ? CORR : DOOR;
300 goto proceed;
301 }
302 nextnxy: ;
303 }
304 nx = x;
305 ny = y;
306 gx = EGD->gdx;
307 gy = EGD->gdy;
308 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
309 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
310 if (abs(gx - x) >= abs(gy - y))
311 nx += dx;
312 else
313 ny += dy;
314
315 while ((typ = (crm = &levl[nx][ny])->typ) != 0) {
316 /*
317 * in view of the above we must have IS_WALL(typ) or typ ==
318 * POOL
319 */
320 /* must be a wall here */
321 if (isok(nx + nx - x, ny + ny - y) && typ != POOL &&
322 ZAP_POS(levl[nx + nx - x][ny + ny - y].typ)) {
323 crm->typ = DOOR;
324 goto proceed;
325 }
326 if (dy && nx != x) {
327 nx = x;
328 ny = y + dy;
329 continue;
330 }
331 if (dx && ny != y) {
332 ny = y;
333 nx = x + dx;
334 dy = 0;
335 continue;
336 }
337 /* I don't like this, but ... */
338 crm->typ = DOOR;
339 goto proceed;
340 }
341 crm->typ = CORR;
342 proceed:
343 if (cansee(nx, ny)) {
344 mnewsym(nx, ny);
345 prl(nx, ny);
346 }
347 fcp = &(EGD->fakecorr[EGD->fcend]);
348 if (EGD->fcend++ == FCSIZ)
349 panic("fakecorr overflow");
350 fcp->fx = nx;
351 fcp->fy = ny;
352 fcp->ftyp = typ;
353 newpos:
354 if (EGD->gddone)
355 nx = ny = 0;
356 guard->mx = nx;
357 guard->my = ny;
358 pmon(guard);
359 restfakecorr();
360 return (1);
361 }
362
363 void
364 gddead()
365 {
366 guard = 0;
367 }
368
369 void
370 replgd(mtmp, mtmp2)
371 struct monst *mtmp, *mtmp2;
372 {
373 if (mtmp == guard)
374 guard = mtmp2;
375 }
376
377 #endif /* QUEST */