hack.vault.c revision 1.9 1 1.9 christos /* $NetBSD: hack.vault.c,v 1.9 2011/08/16 09:26:22 christos Exp $ */
2 1.4 christos
3 1.2 mycroft /*
4 1.6 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 1.6 jsm * Amsterdam
6 1.6 jsm * All rights reserved.
7 1.6 jsm *
8 1.6 jsm * Redistribution and use in source and binary forms, with or without
9 1.6 jsm * modification, are permitted provided that the following conditions are
10 1.6 jsm * met:
11 1.6 jsm *
12 1.6 jsm * - Redistributions of source code must retain the above copyright notice,
13 1.6 jsm * this list of conditions and the following disclaimer.
14 1.6 jsm *
15 1.6 jsm * - Redistributions in binary form must reproduce the above copyright
16 1.6 jsm * notice, this list of conditions and the following disclaimer in the
17 1.6 jsm * documentation and/or other materials provided with the distribution.
18 1.6 jsm *
19 1.6 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en
20 1.6 jsm * Informatica, nor the names of its contributors may be used to endorse or
21 1.6 jsm * promote products derived from this software without specific prior
22 1.6 jsm * written permission.
23 1.6 jsm *
24 1.6 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 1.6 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 1.6 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 1.6 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 1.6 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 1.6 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 1.6 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 1.6 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 1.6 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 1.6 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 1.6 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 1.6 jsm */
36 1.6 jsm
37 1.6 jsm /*
38 1.6 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org>
39 1.6 jsm * All rights reserved.
40 1.6 jsm *
41 1.6 jsm * Redistribution and use in source and binary forms, with or without
42 1.6 jsm * modification, are permitted provided that the following conditions
43 1.6 jsm * are met:
44 1.6 jsm * 1. Redistributions of source code must retain the above copyright
45 1.6 jsm * notice, this list of conditions and the following disclaimer.
46 1.6 jsm * 2. Redistributions in binary form must reproduce the above copyright
47 1.6 jsm * notice, this list of conditions and the following disclaimer in the
48 1.6 jsm * documentation and/or other materials provided with the distribution.
49 1.6 jsm * 3. The name of the author may not be used to endorse or promote products
50 1.6 jsm * derived from this software without specific prior written permission.
51 1.6 jsm *
52 1.6 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 1.6 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 1.6 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 1.6 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 1.6 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 1.6 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 1.6 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 1.6 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 1.6 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 1.6 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 1.2 mycroft */
63 1.2 mycroft
64 1.4 christos #include <sys/cdefs.h>
65 1.2 mycroft #ifndef lint
66 1.9 christos __RCSID("$NetBSD: hack.vault.c,v 1.9 2011/08/16 09:26:22 christos Exp $");
67 1.4 christos #endif /* not lint */
68 1.1 cgd
69 1.4 christos #include "hack.h"
70 1.4 christos #include "extern.h"
71 1.1 cgd #ifdef QUEST
72 1.4 christos void
73 1.8 dholland setgd(void)
74 1.8 dholland {
75 1.4 christos }
76 1.8 dholland
77 1.4 christos int
78 1.8 dholland gd_move(void)
79 1.8 dholland {
80 1.4 christos return (2);
81 1.4 christos }
82 1.8 dholland
83 1.4 christos void
84 1.8 dholland gddead(void)
85 1.4 christos {
86 1.4 christos }
87 1.8 dholland
88 1.4 christos void
89 1.8 dholland replgd(struct monst *mtmp __unused, struct monst *mtmp2 __unused)
90 1.4 christos {
91 1.4 christos }
92 1.8 dholland
93 1.4 christos void
94 1.8 dholland invault(void)
95 1.4 christos {
96 1.4 christos }
97 1.1 cgd
98 1.1 cgd #else
99 1.1 cgd
100 1.1 cgd
101 1.1 cgd #include "def.mkroom.h"
102 1.1 cgd #define FCSIZ (ROWNO+COLNO)
103 1.1 cgd struct fakecorridor {
104 1.4 christos xchar fx, fy, ftyp;
105 1.1 cgd };
106 1.1 cgd
107 1.1 cgd struct egd {
108 1.4 christos int fcbeg, fcend; /* fcend: first unused pos */
109 1.4 christos xchar gdx, gdy; /* goal of guard's walk */
110 1.4 christos unsigned gddone:1;
111 1.1 cgd struct fakecorridor fakecorr[FCSIZ];
112 1.1 cgd };
113 1.1 cgd
114 1.5 jsm static const struct permonst pm_guard =
115 1.4 christos {"guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd)};
116 1.1 cgd
117 1.1 cgd static struct monst *guard;
118 1.4 christos static int gdlevel;
119 1.1 cgd
120 1.7 jsm static void restfakecorr(void);
121 1.7 jsm static int goldincorridor(void);
122 1.4 christos
123 1.4 christos static void
124 1.8 dholland restfakecorr(void)
125 1.1 cgd {
126 1.4 christos int fcx, fcy, fcbeg;
127 1.4 christos struct rm *crm;
128 1.9 christos struct egd *egd = monster_private(guard);
129 1.1 cgd
130 1.9 christos while ((fcbeg = egd->fcbeg) < egd->fcend) {
131 1.9 christos fcx = egd->fakecorr[fcbeg].fx;
132 1.9 christos fcy = egd->fakecorr[fcbeg].fy;
133 1.4 christos if ((u.ux == fcx && u.uy == fcy) || cansee(fcx, fcy) ||
134 1.4 christos m_at(fcx, fcy))
135 1.1 cgd return;
136 1.1 cgd crm = &levl[fcx][fcy];
137 1.9 christos crm->typ = egd->fakecorr[fcbeg].ftyp;
138 1.4 christos if (!crm->typ)
139 1.4 christos crm->seen = 0;
140 1.4 christos newsym(fcx, fcy);
141 1.9 christos egd->fcbeg++;
142 1.1 cgd }
143 1.1 cgd /* it seems he left the corridor - let the guard disappear */
144 1.1 cgd mondead(guard);
145 1.1 cgd guard = 0;
146 1.1 cgd }
147 1.1 cgd
148 1.4 christos static int
149 1.8 dholland goldincorridor(void)
150 1.1 cgd {
151 1.4 christos int fci;
152 1.9 christos struct egd *egd = monster_private(guard);
153 1.1 cgd
154 1.9 christos for (fci = egd->fcbeg; fci < egd->fcend; fci++)
155 1.9 christos if (g_at(egd->fakecorr[fci].fx, egd->fakecorr[fci].fy))
156 1.4 christos return (1);
157 1.4 christos return (0);
158 1.1 cgd }
159 1.1 cgd
160 1.4 christos void
161 1.8 dholland setgd(void)
162 1.4 christos {
163 1.4 christos struct monst *mtmp;
164 1.4 christos for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
165 1.4 christos if (mtmp->isgd) {
166 1.4 christos guard = mtmp;
167 1.4 christos gdlevel = dlevel;
168 1.4 christos return;
169 1.4 christos }
170 1.1 cgd guard = 0;
171 1.1 cgd }
172 1.1 cgd
173 1.4 christos void
174 1.8 dholland invault(void)
175 1.4 christos {
176 1.4 christos int tmp = inroom(u.ux, u.uy);
177 1.9 christos struct egd *egd;
178 1.4 christos if (tmp < 0 || rooms[tmp].rtype != VAULT) {
179 1.4 christos u.uinvault = 0;
180 1.4 christos return;
181 1.1 cgd }
182 1.4 christos if (++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
183 1.4 christos char buf[BUFSZ];
184 1.4 christos int x, y, dd, gx, gy;
185 1.4 christos
186 1.4 christos /* first find the goal for the guard */
187 1.4 christos for (dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
188 1.4 christos for (y = u.uy - dd; y <= u.uy + dd; y++) {
189 1.4 christos if (y < 0 || y > ROWNO - 1)
190 1.4 christos continue;
191 1.4 christos for (x = u.ux - dd; x <= u.ux + dd; x++) {
192 1.4 christos if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
193 1.4 christos x = u.ux + dd;
194 1.4 christos if (x < 0 || x > COLNO - 1)
195 1.4 christos continue;
196 1.4 christos if (levl[x][y].typ == CORR)
197 1.4 christos goto fnd;
198 1.4 christos }
199 1.4 christos }
200 1.4 christos }
201 1.4 christos impossible("Not a single corridor on this level??");
202 1.4 christos tele();
203 1.4 christos return;
204 1.1 cgd fnd:
205 1.4 christos gx = x;
206 1.4 christos gy = y;
207 1.1 cgd
208 1.4 christos /* next find a good place for a door in the wall */
209 1.4 christos x = u.ux;
210 1.4 christos y = u.uy;
211 1.4 christos while (levl[x][y].typ == ROOM) {
212 1.4 christos int dx, dy;
213 1.4 christos
214 1.4 christos dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
215 1.4 christos dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
216 1.4 christos if (abs(gx - x) >= abs(gy - y))
217 1.4 christos x += dx;
218 1.4 christos else
219 1.4 christos y += dy;
220 1.4 christos }
221 1.1 cgd
222 1.4 christos /* make something interesting happen */
223 1.4 christos if (!(guard = makemon(&pm_guard, x, y)))
224 1.4 christos return;
225 1.4 christos guard->isgd = guard->mpeaceful = 1;
226 1.9 christos egd = monster_private(guard);
227 1.9 christos egd->gddone = 0;
228 1.4 christos gdlevel = dlevel;
229 1.4 christos if (!cansee(guard->mx, guard->my)) {
230 1.4 christos mondead(guard);
231 1.4 christos guard = 0;
232 1.4 christos return;
233 1.4 christos }
234 1.4 christos pline("Suddenly one of the Vault's guards enters!");
235 1.4 christos pmon(guard);
236 1.4 christos do {
237 1.4 christos pline("\"Hello stranger, who are you?\" - ");
238 1.4 christos getlin(buf);
239 1.4 christos } while (!letter(buf[0]));
240 1.4 christos
241 1.4 christos if (!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
242 1.4 christos pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
243 1.4 christos mondead(guard);
244 1.4 christos guard = 0;
245 1.4 christos return;
246 1.4 christos }
247 1.4 christos clrlin();
248 1.4 christos pline("\"I don't know you.\"");
249 1.4 christos if (!u.ugold)
250 1.4 christos pline("\"Please follow me.\"");
251 1.4 christos else {
252 1.4 christos pline("\"Most likely all that gold was stolen from this vault.\"");
253 1.4 christos pline("\"Please drop your gold (say d$ ) and follow me.\"");
254 1.4 christos }
255 1.9 christos egd->gdx = gx;
256 1.9 christos egd->gdy = gy;
257 1.9 christos egd->fcbeg = 0;
258 1.9 christos egd->fakecorr[0].fx = x;
259 1.9 christos egd->fakecorr[0].fy = y;
260 1.9 christos egd->fakecorr[0].ftyp = levl[x][y].typ;
261 1.4 christos levl[x][y].typ = DOOR;
262 1.9 christos egd->fcend = 1;
263 1.1 cgd }
264 1.4 christos }
265 1.1 cgd
266 1.4 christos int
267 1.8 dholland gd_move(void)
268 1.4 christos {
269 1.4 christos int x, y, dx, dy, gx, gy, nx, ny, typ;
270 1.4 christos struct fakecorridor *fcp;
271 1.4 christos struct rm *crm;
272 1.9 christos struct egd *egd = monster_private(guard);
273 1.4 christos if (!guard || gdlevel != dlevel) {
274 1.1 cgd impossible("Where is the guard?");
275 1.4 christos return (2); /* died */
276 1.1 cgd }
277 1.4 christos if (u.ugold || goldincorridor())
278 1.4 christos return (0); /* didnt move */
279 1.9 christos if (dist(guard->mx, guard->my) > 1 || egd->gddone) {
280 1.1 cgd restfakecorr();
281 1.4 christos return (0); /* didnt move */
282 1.1 cgd }
283 1.1 cgd x = guard->mx;
284 1.1 cgd y = guard->my;
285 1.1 cgd /* look around (hor & vert only) for accessible places */
286 1.4 christos for (nx = x - 1; nx <= x + 1; nx++)
287 1.4 christos for (ny = y - 1; ny <= y + 1; ny++) {
288 1.4 christos if (nx == x || ny == y)
289 1.4 christos if (nx != x || ny != y)
290 1.4 christos if (isok(nx, ny))
291 1.4 christos if (!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
292 1.4 christos int i;
293 1.9 christos for (i = egd->fcbeg; i < egd->fcend; i++)
294 1.9 christos if (egd->fakecorr[i].fx == nx &&
295 1.9 christos egd->fakecorr[i].fy == ny)
296 1.4 christos goto nextnxy;
297 1.4 christos if ((i = inroom(nx, ny)) >= 0 && rooms[i].rtype == VAULT)
298 1.4 christos goto nextnxy;
299 1.4 christos /*
300 1.4 christos * seems we found a
301 1.4 christos * good place to
302 1.4 christos * leave him alone
303 1.4 christos */
304 1.9 christos egd->gddone = 1;
305 1.4 christos if (ACCESSIBLE(typ))
306 1.4 christos goto newpos;
307 1.4 christos crm->typ = (typ == SCORR) ? CORR : DOOR;
308 1.4 christos goto proceed;
309 1.4 christos }
310 1.4 christos nextnxy: ;
311 1.4 christos }
312 1.1 cgd nx = x;
313 1.1 cgd ny = y;
314 1.9 christos gx = egd->gdx;
315 1.9 christos gy = egd->gdy;
316 1.1 cgd dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
317 1.1 cgd dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
318 1.4 christos if (abs(gx - x) >= abs(gy - y))
319 1.4 christos nx += dx;
320 1.4 christos else
321 1.4 christos ny += dy;
322 1.4 christos
323 1.4 christos while ((typ = (crm = &levl[nx][ny])->typ) != 0) {
324 1.4 christos /*
325 1.4 christos * in view of the above we must have IS_WALL(typ) or typ ==
326 1.4 christos * POOL
327 1.4 christos */
328 1.4 christos /* must be a wall here */
329 1.4 christos if (isok(nx + nx - x, ny + ny - y) && typ != POOL &&
330 1.4 christos ZAP_POS(levl[nx + nx - x][ny + ny - y].typ)) {
331 1.1 cgd crm->typ = DOOR;
332 1.1 cgd goto proceed;
333 1.1 cgd }
334 1.4 christos if (dy && nx != x) {
335 1.4 christos nx = x;
336 1.4 christos ny = y + dy;
337 1.1 cgd continue;
338 1.1 cgd }
339 1.4 christos if (dx && ny != y) {
340 1.4 christos ny = y;
341 1.4 christos nx = x + dx;
342 1.4 christos dy = 0;
343 1.1 cgd continue;
344 1.1 cgd }
345 1.1 cgd /* I don't like this, but ... */
346 1.1 cgd crm->typ = DOOR;
347 1.1 cgd goto proceed;
348 1.1 cgd }
349 1.1 cgd crm->typ = CORR;
350 1.1 cgd proceed:
351 1.4 christos if (cansee(nx, ny)) {
352 1.4 christos mnewsym(nx, ny);
353 1.4 christos prl(nx, ny);
354 1.1 cgd }
355 1.9 christos fcp = &(egd->fakecorr[egd->fcend]);
356 1.9 christos if (egd->fcend++ == FCSIZ)
357 1.4 christos panic("fakecorr overflow");
358 1.1 cgd fcp->fx = nx;
359 1.1 cgd fcp->fy = ny;
360 1.1 cgd fcp->ftyp = typ;
361 1.1 cgd newpos:
362 1.9 christos if (egd->gddone)
363 1.4 christos nx = ny = 0;
364 1.1 cgd guard->mx = nx;
365 1.1 cgd guard->my = ny;
366 1.1 cgd pmon(guard);
367 1.1 cgd restfakecorr();
368 1.4 christos return (1);
369 1.1 cgd }
370 1.1 cgd
371 1.4 christos void
372 1.8 dholland gddead(void)
373 1.4 christos {
374 1.1 cgd guard = 0;
375 1.1 cgd }
376 1.1 cgd
377 1.4 christos void
378 1.8 dholland replgd(struct monst *mtmp, struct monst *mtmp2)
379 1.1 cgd {
380 1.4 christos if (mtmp == guard)
381 1.1 cgd guard = mtmp2;
382 1.1 cgd }
383 1.1 cgd
384 1.4 christos #endif /* QUEST */
385