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