hack.vault.c revision 1.5 1 1.5 jsm /* $NetBSD: hack.vault.c,v 1.5 2001/03/25 20:44:03 jsm Exp $ */
2 1.4 christos
3 1.2 mycroft /*
4 1.2 mycroft * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5 1.2 mycroft */
6 1.2 mycroft
7 1.4 christos #include <sys/cdefs.h>
8 1.2 mycroft #ifndef lint
9 1.5 jsm __RCSID("$NetBSD: hack.vault.c,v 1.5 2001/03/25 20:44:03 jsm Exp $");
10 1.4 christos #endif /* not lint */
11 1.1 cgd
12 1.4 christos #include "hack.h"
13 1.4 christos #include "extern.h"
14 1.1 cgd #ifdef QUEST
15 1.4 christos void
16 1.4 christos setgd( /* mtmp */ )
17 1.4 christos { /* struct monst *mtmp; */
18 1.4 christos }
19 1.4 christos int
20 1.4 christos gd_move() {
21 1.4 christos return (2);
22 1.4 christos }
23 1.4 christos void
24 1.4 christos gddead()
25 1.4 christos {
26 1.4 christos }
27 1.4 christos void
28 1.4 christos replgd(mtmp, mtmp2)
29 1.4 christos struct monst *mtmp, *mtmp2;
30 1.4 christos {
31 1.4 christos }
32 1.4 christos void
33 1.4 christos invault()
34 1.4 christos {
35 1.4 christos }
36 1.1 cgd
37 1.1 cgd #else
38 1.1 cgd
39 1.1 cgd
40 1.1 cgd #include "def.mkroom.h"
41 1.1 cgd #define FCSIZ (ROWNO+COLNO)
42 1.1 cgd struct fakecorridor {
43 1.4 christos xchar fx, fy, ftyp;
44 1.1 cgd };
45 1.1 cgd
46 1.1 cgd struct egd {
47 1.4 christos int fcbeg, fcend; /* fcend: first unused pos */
48 1.4 christos xchar gdx, gdy; /* goal of guard's walk */
49 1.4 christos unsigned gddone:1;
50 1.1 cgd struct fakecorridor fakecorr[FCSIZ];
51 1.1 cgd };
52 1.1 cgd
53 1.5 jsm static const struct permonst pm_guard =
54 1.4 christos {"guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd)};
55 1.1 cgd
56 1.1 cgd static struct monst *guard;
57 1.4 christos static int gdlevel;
58 1.1 cgd #define EGD ((struct egd *)(&(guard->mextra[0])))
59 1.1 cgd
60 1.4 christos static void restfakecorr __P((void));
61 1.4 christos static int goldincorridor __P((void));
62 1.4 christos
63 1.4 christos static void
64 1.1 cgd restfakecorr()
65 1.1 cgd {
66 1.4 christos int fcx, fcy, fcbeg;
67 1.4 christos struct rm *crm;
68 1.1 cgd
69 1.4 christos while ((fcbeg = EGD->fcbeg) < EGD->fcend) {
70 1.1 cgd fcx = EGD->fakecorr[fcbeg].fx;
71 1.1 cgd fcy = EGD->fakecorr[fcbeg].fy;
72 1.4 christos if ((u.ux == fcx && u.uy == fcy) || cansee(fcx, fcy) ||
73 1.4 christos m_at(fcx, fcy))
74 1.1 cgd return;
75 1.1 cgd crm = &levl[fcx][fcy];
76 1.1 cgd crm->typ = EGD->fakecorr[fcbeg].ftyp;
77 1.4 christos if (!crm->typ)
78 1.4 christos crm->seen = 0;
79 1.4 christos newsym(fcx, fcy);
80 1.1 cgd EGD->fcbeg++;
81 1.1 cgd }
82 1.1 cgd /* it seems he left the corridor - let the guard disappear */
83 1.1 cgd mondead(guard);
84 1.1 cgd guard = 0;
85 1.1 cgd }
86 1.1 cgd
87 1.4 christos static int
88 1.1 cgd goldincorridor()
89 1.1 cgd {
90 1.4 christos int fci;
91 1.1 cgd
92 1.4 christos for (fci = EGD->fcbeg; fci < EGD->fcend; fci++)
93 1.4 christos if (g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy))
94 1.4 christos return (1);
95 1.4 christos return (0);
96 1.1 cgd }
97 1.1 cgd
98 1.4 christos void
99 1.4 christos setgd()
100 1.4 christos {
101 1.4 christos struct monst *mtmp;
102 1.4 christos for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
103 1.4 christos if (mtmp->isgd) {
104 1.4 christos guard = mtmp;
105 1.4 christos gdlevel = dlevel;
106 1.4 christos return;
107 1.4 christos }
108 1.1 cgd guard = 0;
109 1.1 cgd }
110 1.1 cgd
111 1.4 christos void
112 1.4 christos invault()
113 1.4 christos {
114 1.4 christos int tmp = inroom(u.ux, u.uy);
115 1.4 christos if (tmp < 0 || rooms[tmp].rtype != VAULT) {
116 1.4 christos u.uinvault = 0;
117 1.4 christos return;
118 1.1 cgd }
119 1.4 christos if (++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
120 1.4 christos char buf[BUFSZ];
121 1.4 christos int x, y, dd, gx, gy;
122 1.4 christos
123 1.4 christos /* first find the goal for the guard */
124 1.4 christos for (dd = 1; (dd < ROWNO || dd < COLNO); dd++) {
125 1.4 christos for (y = u.uy - dd; y <= u.uy + dd; y++) {
126 1.4 christos if (y < 0 || y > ROWNO - 1)
127 1.4 christos continue;
128 1.4 christos for (x = u.ux - dd; x <= u.ux + dd; x++) {
129 1.4 christos if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
130 1.4 christos x = u.ux + dd;
131 1.4 christos if (x < 0 || x > COLNO - 1)
132 1.4 christos continue;
133 1.4 christos if (levl[x][y].typ == CORR)
134 1.4 christos goto fnd;
135 1.4 christos }
136 1.4 christos }
137 1.4 christos }
138 1.4 christos impossible("Not a single corridor on this level??");
139 1.4 christos tele();
140 1.4 christos return;
141 1.1 cgd fnd:
142 1.4 christos gx = x;
143 1.4 christos gy = y;
144 1.1 cgd
145 1.4 christos /* next find a good place for a door in the wall */
146 1.4 christos x = u.ux;
147 1.4 christos y = u.uy;
148 1.4 christos while (levl[x][y].typ == ROOM) {
149 1.4 christos int dx, dy;
150 1.4 christos
151 1.4 christos dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
152 1.4 christos dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
153 1.4 christos if (abs(gx - x) >= abs(gy - y))
154 1.4 christos x += dx;
155 1.4 christos else
156 1.4 christos y += dy;
157 1.4 christos }
158 1.1 cgd
159 1.4 christos /* make something interesting happen */
160 1.4 christos if (!(guard = makemon(&pm_guard, x, y)))
161 1.4 christos return;
162 1.4 christos guard->isgd = guard->mpeaceful = 1;
163 1.4 christos EGD->gddone = 0;
164 1.4 christos gdlevel = dlevel;
165 1.4 christos if (!cansee(guard->mx, guard->my)) {
166 1.4 christos mondead(guard);
167 1.4 christos guard = 0;
168 1.4 christos return;
169 1.4 christos }
170 1.4 christos pline("Suddenly one of the Vault's guards enters!");
171 1.4 christos pmon(guard);
172 1.4 christos do {
173 1.4 christos pline("\"Hello stranger, who are you?\" - ");
174 1.4 christos getlin(buf);
175 1.4 christos } while (!letter(buf[0]));
176 1.4 christos
177 1.4 christos if (!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
178 1.4 christos pline("\"Oh, yes - of course. Sorry to have disturbed you.\"");
179 1.4 christos mondead(guard);
180 1.4 christos guard = 0;
181 1.4 christos return;
182 1.4 christos }
183 1.4 christos clrlin();
184 1.4 christos pline("\"I don't know you.\"");
185 1.4 christos if (!u.ugold)
186 1.4 christos pline("\"Please follow me.\"");
187 1.4 christos else {
188 1.4 christos pline("\"Most likely all that gold was stolen from this vault.\"");
189 1.4 christos pline("\"Please drop your gold (say d$ ) and follow me.\"");
190 1.4 christos }
191 1.4 christos EGD->gdx = gx;
192 1.4 christos EGD->gdy = gy;
193 1.4 christos EGD->fcbeg = 0;
194 1.4 christos EGD->fakecorr[0].fx = x;
195 1.4 christos EGD->fakecorr[0].fy = y;
196 1.4 christos EGD->fakecorr[0].ftyp = levl[x][y].typ;
197 1.4 christos levl[x][y].typ = DOOR;
198 1.4 christos EGD->fcend = 1;
199 1.1 cgd }
200 1.4 christos }
201 1.1 cgd
202 1.4 christos int
203 1.4 christos gd_move()
204 1.4 christos {
205 1.4 christos int x, y, dx, dy, gx, gy, nx, ny, typ;
206 1.4 christos struct fakecorridor *fcp;
207 1.4 christos struct rm *crm;
208 1.4 christos if (!guard || gdlevel != dlevel) {
209 1.1 cgd impossible("Where is the guard?");
210 1.4 christos return (2); /* died */
211 1.1 cgd }
212 1.4 christos if (u.ugold || goldincorridor())
213 1.4 christos return (0); /* didnt move */
214 1.4 christos if (dist(guard->mx, guard->my) > 1 || EGD->gddone) {
215 1.1 cgd restfakecorr();
216 1.4 christos return (0); /* didnt move */
217 1.1 cgd }
218 1.1 cgd x = guard->mx;
219 1.1 cgd y = guard->my;
220 1.1 cgd /* look around (hor & vert only) for accessible places */
221 1.4 christos for (nx = x - 1; nx <= x + 1; nx++)
222 1.4 christos for (ny = y - 1; ny <= y + 1; ny++) {
223 1.4 christos if (nx == x || ny == y)
224 1.4 christos if (nx != x || ny != y)
225 1.4 christos if (isok(nx, ny))
226 1.4 christos if (!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) {
227 1.4 christos int i;
228 1.4 christos for (i = EGD->fcbeg; i < EGD->fcend; i++)
229 1.4 christos if (EGD->fakecorr[i].fx == nx &&
230 1.4 christos EGD->fakecorr[i].fy == ny)
231 1.4 christos goto nextnxy;
232 1.4 christos if ((i = inroom(nx, ny)) >= 0 && rooms[i].rtype == VAULT)
233 1.4 christos goto nextnxy;
234 1.4 christos /*
235 1.4 christos * seems we found a
236 1.4 christos * good place to
237 1.4 christos * leave him alone
238 1.4 christos */
239 1.4 christos EGD->gddone = 1;
240 1.4 christos if (ACCESSIBLE(typ))
241 1.4 christos goto newpos;
242 1.4 christos crm->typ = (typ == SCORR) ? CORR : DOOR;
243 1.4 christos goto proceed;
244 1.4 christos }
245 1.4 christos nextnxy: ;
246 1.4 christos }
247 1.1 cgd nx = x;
248 1.1 cgd ny = y;
249 1.1 cgd gx = EGD->gdx;
250 1.1 cgd gy = EGD->gdy;
251 1.1 cgd dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
252 1.1 cgd dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
253 1.4 christos if (abs(gx - x) >= abs(gy - y))
254 1.4 christos nx += dx;
255 1.4 christos else
256 1.4 christos ny += dy;
257 1.4 christos
258 1.4 christos while ((typ = (crm = &levl[nx][ny])->typ) != 0) {
259 1.4 christos /*
260 1.4 christos * in view of the above we must have IS_WALL(typ) or typ ==
261 1.4 christos * POOL
262 1.4 christos */
263 1.4 christos /* must be a wall here */
264 1.4 christos if (isok(nx + nx - x, ny + ny - y) && typ != POOL &&
265 1.4 christos ZAP_POS(levl[nx + nx - x][ny + ny - y].typ)) {
266 1.1 cgd crm->typ = DOOR;
267 1.1 cgd goto proceed;
268 1.1 cgd }
269 1.4 christos if (dy && nx != x) {
270 1.4 christos nx = x;
271 1.4 christos ny = y + dy;
272 1.1 cgd continue;
273 1.1 cgd }
274 1.4 christos if (dx && ny != y) {
275 1.4 christos ny = y;
276 1.4 christos nx = x + dx;
277 1.4 christos dy = 0;
278 1.1 cgd continue;
279 1.1 cgd }
280 1.1 cgd /* I don't like this, but ... */
281 1.1 cgd crm->typ = DOOR;
282 1.1 cgd goto proceed;
283 1.1 cgd }
284 1.1 cgd crm->typ = CORR;
285 1.1 cgd proceed:
286 1.4 christos if (cansee(nx, ny)) {
287 1.4 christos mnewsym(nx, ny);
288 1.4 christos prl(nx, ny);
289 1.1 cgd }
290 1.1 cgd fcp = &(EGD->fakecorr[EGD->fcend]);
291 1.4 christos if (EGD->fcend++ == FCSIZ)
292 1.4 christos panic("fakecorr overflow");
293 1.1 cgd fcp->fx = nx;
294 1.1 cgd fcp->fy = ny;
295 1.1 cgd fcp->ftyp = typ;
296 1.1 cgd newpos:
297 1.4 christos if (EGD->gddone)
298 1.4 christos nx = ny = 0;
299 1.1 cgd guard->mx = nx;
300 1.1 cgd guard->my = ny;
301 1.1 cgd pmon(guard);
302 1.1 cgd restfakecorr();
303 1.4 christos return (1);
304 1.1 cgd }
305 1.1 cgd
306 1.4 christos void
307 1.4 christos gddead()
308 1.4 christos {
309 1.1 cgd guard = 0;
310 1.1 cgd }
311 1.1 cgd
312 1.4 christos void
313 1.4 christos replgd(mtmp, mtmp2)
314 1.4 christos struct monst *mtmp, *mtmp2;
315 1.1 cgd {
316 1.4 christos if (mtmp == guard)
317 1.1 cgd guard = mtmp2;
318 1.1 cgd }
319 1.1 cgd
320 1.4 christos #endif /* QUEST */
321