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