1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64: #include <sys/cdefs.h>
65: #ifndef lint
66: __RCSID("$NetBSD: hack.vault.c,v 1.7 2004/01/27 20:30:29 jsm Exp $");
67: #endif
68:
69: #include "hack.h"
70: #include "extern.h"
71: #ifdef QUEST
72: void
73: setgd( )
74: {
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;
105: xchar gdx, gdy;
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(void);
118: static int goldincorridor(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:
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:
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:
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:
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);
268: }
269: if (u.ugold || goldincorridor())
270: return (0);
271: if (dist(guard->mx, guard->my) > 1 || EGD->gddone) {
272: restfakecorr();
273: return (0);
274: }
275: x = guard->mx;
276: y = guard->my;
277:
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:
293:
294:
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:
318:
319:
320:
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:
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