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