1    | /*	SCCS Id: @(#)vault.c	3.3	96/06/05	*/
2    | /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3    | /* NetHack may be freely redistributed.  See license for details. */
4    | 
5    | #include "hack.h"
6    | #include "vault.h"
7    | 
8    | STATIC_DCL struct monst *NDECL(findgd);
9    | 
10   | #ifdef OVLB
11   | 
12   | STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *,BOOLEAN_P));
13   | STATIC_DCL void FDECL(restfakecorr,(struct monst *));
14   | STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *,int,int));
15   | STATIC_DCL void FDECL(move_gold,(struct obj *,int));
16   | STATIC_DCL void FDECL(wallify_vault,(struct monst *));
17   | 
18   | STATIC_OVL boolean
19   | clear_fcorr(grd, forceshow)
20   | register struct monst *grd;
21   | register boolean forceshow;
22   | {
23   | 	register int fcx, fcy, fcbeg;
24   | 	register struct monst *mtmp;
25   | 
26   | 	while((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
27   | 		fcx = EGD(grd)->fakecorr[fcbeg].fx;
28   | 		fcy = EGD(grd)->fakecorr[fcbeg].fy;
29   | 		if((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
30   | 				   EGD(grd)->gddone)
31   | 			forceshow = TRUE;
32   | 		if((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
33   | 			|| (!forceshow && couldsee(fcx,fcy))
34   | 			|| (Punished && !carried(uball)
35   | 				&& uball->ox == fcx && uball->oy == fcy))
36   | 			return FALSE;
37   | 
38   | 		if ((mtmp = m_at(fcx,fcy)) != 0) {
39   | 			if(mtmp->isgd) return(FALSE);
40   | 			else if(!in_fcorridor(grd, u.ux, u.uy)) {
41   | 			    if(mtmp->mtame) yelp(mtmp);
42   | 			    rloc(mtmp);
43   | 			}
44   | 		}
45   | 		levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
46   | 		map_location(fcx, fcy, 1);	/* bypass vision */
47   | 		if(!ACCESSIBLE(levl[fcx][fcy].typ)) block_point(fcx,fcy);
48   | 		EGD(grd)->fcbeg++;
49   | 	}
50   | 	if(grd->mhp <= 0) {
51   | 	    pline_The("corridor disappears.");
52   | 	    if(IS_ROCK(levl[u.ux][u.uy].typ)) You("are encased in rock.");
53   | 	}
54   | 	return(TRUE);
55   | }
56   | 
57   | STATIC_OVL void
58   | restfakecorr(grd)
59   | register struct monst *grd;
60   | {
61   | 	/* it seems you left the corridor - let the guard disappear */
62   | 	if(clear_fcorr(grd, FALSE)) mongone(grd);
63   | }
64   | 
65   | boolean
66   | grddead(grd)				/* called in mon.c */
67   | register struct monst *grd;
68   | {
69   | 	register boolean dispose = clear_fcorr(grd, TRUE);
70   | 
71   | 	if(!dispose) {
72   | 		/* see comment by newpos in gd_move() */
73   | 		remove_monster(grd->mx, grd->my);
74   | 		newsym(grd->mx, grd->my);
75   | 		place_monster(grd, 0, 0);
76   | 		EGD(grd)->ogx = grd->mx;
77   | 		EGD(grd)->ogy = grd->my;
78   | 		dispose = clear_fcorr(grd, TRUE);
79   | 	}
80   | 	return(dispose);
81   | }
82   | 
83   | STATIC_OVL boolean
84   | in_fcorridor(grd, x, y)
85   | register struct monst *grd;
86   | int x, y;
87   | {
88   | 	register int fci;
89   | 
90   | 	for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++)
91   | 		if(x == EGD(grd)->fakecorr[fci].fx &&
92   | 				y == EGD(grd)->fakecorr[fci].fy)
93   | 			return(TRUE);
94   | 	return(FALSE);
95   | }
96   | 
97   | STATIC_OVL
98   | struct monst *
99   | findgd()
100  | {
101  | 	register struct monst *mtmp;
102  | 
103  | 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
104  | 	    if(mtmp->isgd && !DEADMONSTER(mtmp) && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
105  | 		return(mtmp);
106  | 	return((struct monst *)0);
107  | }
108  | 
109  | #endif /* OVLB */
110  | #ifdef OVL0
111  | 
112  | char
113  | vault_occupied(array)
114  | char *array;
115  | {
116  | 	register char *ptr;
117  | 
118  | 	for (ptr = array; *ptr; ptr++)
119  | 		if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
120  | 			return(*ptr);
121  | 	return('\0');
122  | }
123  | 
124  | void
125  | invault()
126  | {
127  | #ifdef BSD_43_BUG
128  |     int dummy;		/* hack to avoid schain botch */
129  | #endif
130  |     struct monst *guard;
131  |     int vaultroom = (int)vault_occupied(u.urooms);
132  | 
133  |     if(!vaultroom) {
134  | 	u.uinvault = 0;
135  | 	return;
136  |     }
137  | 
138  |     vaultroom -= ROOMOFFSET;
139  | 
140  |     guard = findgd();
141  |     if(++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
142  | 	char buf[BUFSZ];
143  | 	register int x, y, dd, gx, gy;
144  | 	int lx = 0, ly = 0;
145  | 
146  | 	/* first find the goal for the guard */
147  | 	for(dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
148  | 	  for(y = u.uy-dd; y <= u.uy+dd; ly = y, y++) {
149  | 	    if(y < 0 || y > ROWNO-1) continue;
150  | 	    for(x = u.ux-dd; x <= u.ux+dd; lx = x, x++) {
151  | 	      if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
152  | 		x = u.ux+dd;
153  | 	      if(x < 1 || x > COLNO-1) continue;
154  | 	      if(levl[x][y].typ == CORR) {
155  | 		  if(x < u.ux) lx = x + 1;
156  | 		  else if(x > u.ux) lx = x - 1;
157  | 		  else lx = x;
158  | 		  if(y < u.uy) ly = y + 1;
159  | 		  else if(y > u.uy) ly = y - 1;
160  | 		  else ly = y;
161  | 		  if(levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
162  | 		      goto incr_radius;
163  | 		  goto fnd;
164  | 	      }
165  | 	    }
166  | 	  }
167  | incr_radius: ;
168  | 	}
169  | 	impossible("Not a single corridor on this level??");
170  | 	tele();
171  | 	return;
172  | fnd:
173  | 	gx = x; gy = y;
174  | 
175  | 	/* next find a good place for a door in the wall */
176  | 	x = u.ux; y = u.uy;
177  | 	if(levl[x][y].typ != ROOM) {  /* player dug a door and is in it */
178  | 		if(levl[x+1][y].typ == ROOM)  x = x + 1;
179  | 		else if(levl[x][y+1].typ == ROOM) y = y + 1;
180  | 		else if(levl[x-1][y].typ == ROOM) x = x - 1;
181  | 		else if(levl[x][y-1].typ == ROOM) y = y - 1;
182  | 		else if(levl[x+1][y+1].typ == ROOM) {
183  | 			x = x + 1;
184  | 			y = y + 1;
185  | 		} else if (levl[x-1][y-1].typ == ROOM) {
186  | 			x = x - 1;
187  | 			y = y - 1;
188  | 		} else if (levl[x+1][y-1].typ == ROOM) {
189  | 			x = x + 1;
190  | 			y = y - 1;
191  | 		} else if (levl[x-1][y+1].typ == ROOM) {
192  | 			x = x - 1;
193  | 			y = y + 1;
194  | 		}
195  | 	}
196  | 	while(levl[x][y].typ == ROOM) {
197  | 		register int dx,dy;
198  | 
199  | 		dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
200  | 		dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
201  | 		if(abs(gx-x) >= abs(gy-y))
202  | 			x += dx;
203  | 		else
204  | 			y += dy;
205  | 	}
206  | 	if(x == u.ux && y == u.uy) {
207  | 		if(levl[x+1][y].typ == HWALL || levl[x+1][y].typ == DOOR)
208  | 			x = x + 1;
209  | 		else if(levl[x-1][y].typ == HWALL || levl[x-1][y].typ == DOOR)
210  | 			x = x - 1;
211  | 		else if(levl[x][y+1].typ == VWALL || levl[x][y+1].typ == DOOR)
212  | 			y = y + 1;
213  | 		else if(levl[x][y-1].typ == VWALL || levl[x][y-1].typ == DOOR)
214  | 			y = y - 1;
215  | 		else return;
216  | 	}
217  | 
218  | 	/* make something interesting happen */
219  | 	if(!(guard = makemon(&mons[PM_GUARD], x, y, NO_MM_FLAGS))) return;
220  | 	guard->isgd = 1;
221  | 	guard->mpeaceful = 1;
222  | 	set_malign(guard);
223  | 	EGD(guard)->gddone = 0;
224  | 	EGD(guard)->ogx = x;
225  | 	EGD(guard)->ogy = y;
226  | 	assign_level(&(EGD(guard)->gdlevel), &u.uz);
227  | 	EGD(guard)->vroom = vaultroom;
228  | 	EGD(guard)->warncnt = 0;
229  | 
230  | 	if(!cansee(guard->mx, guard->my)) {
231  | 		mongone(guard);
232  | 		return;
233  | 	}
234  | 
235  | 	reset_faint();			/* if fainted - wake up */
236  | 	pline("Suddenly one of the Vault's guards enters!");
237  | 	newsym(guard->mx,guard->my);
238  | 	if (Strangled || youmonst.data->msound == MS_SILENT) {
239  | 	    verbalize("I'll be back when you're ready to speak to me!");
240  | 	    mongone(guard);
241  | 	    return;
242  | 	}
243  | 	stop_occupation();		/* if occupied, stop it *now* */
244  | 	do {
245  | 		getlin("\"Hello stranger, who are you?\" -",buf);
246  | 	} while (!letter(buf[0]));
247  | 
248  | 	if (u.ualign.type == A_LAWFUL &&
249  | 	    /* ignore trailing text, in case player includes character's rank */
250  | 	    strncmpi(buf, plname, (int) strlen(plname)) != 0) {
251  | 		adjalign(-1);		/* Liar! */
252  | 	}
253  | 
254  | 	if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
255  | #ifdef TOURIST
256  | 		|| !strcmpi(buf, "Creosote")
257  | #endif
258  | 	    ) {
259  | 	    if (!mvitals[PM_CROESUS].died) {
260  | 		verbalize("Oh, yes, of course.  Sorry to have disturbed you.");
261  | 		mongone(guard);
262  | 	    } else {
263  | 		setmangry(guard);
264  | 		verbalize("Back from the dead, are you?  I'll remedy that!");
265  | 		/* don't want guard to waste next turn wielding a weapon */
266  | 		if (!MON_WEP(guard)) {
267  | 		    guard->weapon_check = NEED_HTH_WEAPON;
268  | 		    (void) mon_wield_item(guard);
269  | 		}
270  | 	    }
271  | 	    return;
272  | 	}
273  | 	verbalize("I don't know you.");
274  | 	if (!u.ugold && !hidden_gold())
275  | 	    verbalize("Please follow me.");
276  | 	else {
277  | 	    if (!u.ugold)
278  | 		verbalize("You have hidden gold.");
279  | 	    verbalize("Most likely all your gold was stolen from this vault.");
280  | 	    verbalize("Please drop that gold and follow me.");
281  | 	}
282  | 	EGD(guard)->gdx = gx;
283  | 	EGD(guard)->gdy = gy;
284  | 	EGD(guard)->fcbeg = 0;
285  | 	EGD(guard)->fakecorr[0].fx = x;
286  | 	EGD(guard)->fakecorr[0].fy = y;
287  | 	if(IS_WALL(levl[x][y].typ))
288  | 	    EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
289  | 	else { /* the initial guard location is a dug door */
290  | 	    int vlt = EGD(guard)->vroom;
291  | 	    xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
292  | 	    xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
293  | 
294  | 	    if(x == lowx-1 && y == lowy-1)
295  | 		EGD(guard)->fakecorr[0].ftyp = TLCORNER;
296  | 	    else if(x == hix+1 && y == lowy-1)
297  | 		EGD(guard)->fakecorr[0].ftyp = TRCORNER;
298  | 	    else if(x == lowx-1 && y == hiy+1)
299  | 		EGD(guard)->fakecorr[0].ftyp = BLCORNER;
300  | 	    else if(x == hix+1 && y == hiy+1)
301  | 		EGD(guard)->fakecorr[0].ftyp = BRCORNER;
302  | 	    else if(y == lowy-1 || y == hiy+1)
303  | 		EGD(guard)->fakecorr[0].ftyp = HWALL;
304  | 	    else if(x == lowx-1 || x == hix+1)
305  | 		EGD(guard)->fakecorr[0].ftyp = VWALL;
306  | 	}
307  | 	levl[x][y].typ = DOOR;
308  | 	levl[x][y].doormask = D_NODOOR;
309  | 	unblock_point(x, y);		/* doesn't block light */
310  | 	EGD(guard)->fcend = 1;
311  | 	EGD(guard)->warncnt = 1;
312  |     }
313  | }
314  | 
315  | #endif /* OVL0 */
316  | #ifdef OVLB
317  | 
318  | STATIC_OVL void
319  | move_gold(gold, vroom)
320  | struct obj *gold;
321  | int vroom;
322  | {
323  | 	xchar nx, ny;
324  | 
325  | 	remove_object(gold);
326  | 	newsym(gold->ox, gold->oy);
327  | 	nx = rooms[vroom].lx + rn2(2);
328  | 	ny = rooms[vroom].ly + rn2(2);
329  | 	place_object(gold, nx, ny);
330  | 	stackobj(gold);
331  | 	newsym(nx,ny);
332  | }
333  | 
334  | STATIC_OVL void
335  | wallify_vault(grd)
336  | struct monst *grd;
337  | {
338  | 	int x, y;
339  | 	int vlt = EGD(grd)->vroom;
340  | 	char tmp_viz;
341  | 	xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
342  | 	xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
343  | 	register struct obj *gold;
344  | 	register boolean fixed = FALSE;
345  | 	register boolean movedgold = FALSE;
346  | 
347  | 	for(x = lowx-1; x <= hix+1; x++)
348  | 	    for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
349  | 		if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
350  | 		    if(MON_AT(x, y) && grd->mx != x && grd->my != y) {
351  | 			struct monst *mon = m_at(x,y);
352  | 			if (mon->mtame) yelp(mon);
353  | 			rloc(mon);
354  | 		    }
355  | 		    if ((gold = g_at(x, y)) != 0) {
356  | 			move_gold(gold, EGD(grd)->vroom);
357  | 			movedgold = TRUE;
358  | 		    }
359  | 		    if(x == lowx-1 && y == lowy-1)
360  | 			levl[x][y].typ = TLCORNER;
361  | 		    else if(x == hix+1 && y == lowy-1)
362  | 			levl[x][y].typ = TRCORNER;
363  | 		    else if(x == lowx-1 && y == hiy+1)
364  | 			levl[x][y].typ = BLCORNER;
365  | 		    else if(x == hix+1 && y == hiy+1)
366  | 			levl[x][y].typ = BRCORNER;
367  | 		    else levl[x][y].typ = HWALL;
368  | 
369  | 		    levl[x][y].doormask = 0;
370  | 		    /*
371  | 		     * hack: player knows walls are restored because of the
372  | 		     * message, below, so show this on the screen.
373  | 		     */
374  | 		    tmp_viz = viz_array[y][x];
375  | 		    viz_array[y][x] = IN_SIGHT|COULD_SEE;
376  | 		    newsym(x,y);
377  | 		    viz_array[y][x] = tmp_viz;
378  | 		    block_point(x,y);
379  | 		    fixed = TRUE;
380  | 		}
381  | 	    }
382  | 	for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
383  | 	    for(y = lowy; y <= hiy; y++) {
384  | 		if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
385  | 		    if(MON_AT(x, y) && grd->mx != x && grd->my != y) {
386  | 			struct monst *mon = m_at(x,y);
387  | 			if (mon->mtame) yelp(mon);
388  | 			rloc(mon);
389  | 		    }
390  | 		    if ((gold = g_at(x, y)) != 0) {
391  | 			move_gold(gold, EGD(grd)->vroom);
392  | 			movedgold = TRUE;
393  | 		    }
394  | 		    levl[x][y].typ = VWALL;
395  | 		    levl[x][y].doormask = 0;
396  | 		    tmp_viz = viz_array[y][x];
397  | 		    viz_array[y][x] = IN_SIGHT|COULD_SEE;
398  | 		    newsym(x,y);
399  | 		    viz_array[y][x] = tmp_viz;
400  | 		    block_point(x,y);
401  | 		    fixed = TRUE;
402  | 		}
403  | 	    }
404  | 
405  | 	if(movedgold || fixed) {
406  | 	    if(in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
407  | 		pline_The("guard whispers an incantation.");
408  | 	    else You_hear("a distant chant.");
409  | 	    if(movedgold)
410  | 		pline("A mysterious force moves the gold into the vault.");
411  | 	    if(fixed)
412  | 		pline_The("damaged vault's walls are magically restored!");
413  | 	}
414  | }
415  | 
416  | /*
417  |  * return  1: guard moved,  0: guard didn't,  -1: let m_move do it,  -2: died
418  |  */
419  | int
420  | gd_move(grd)
421  | register struct monst *grd;
422  | {
423  | 	int x, y, nx, ny, m, n;
424  | 	int dx, dy, gx, gy, fci;
425  | 	uchar typ;
426  | 	struct fakecorridor *fcp;
427  | 	register struct egd *egrd = EGD(grd);
428  | 	register struct rm *crm;
429  | 	register boolean goldincorridor = FALSE,
430  | 			 u_in_vault = vault_occupied(u.urooms)? TRUE : FALSE,
431  | 			 grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT)?
432  | 					TRUE : FALSE;
433  | 	boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
434  | 	register boolean u_carry_gold = ((u.ugold + hidden_gold()) > 0L);
435  | 
436  | 	if(!on_level(&(egrd->gdlevel), &u.uz)) return(-1);
437  | 	nx = ny = m = n = 0;
438  | 	if(!u_in_vault && !grd_in_vault)
439  | 	    wallify_vault(grd);
440  | 	if(!grd->mpeaceful) {
441  | 	    if(semi_dead) {
442  | 		egrd->gddone =1;
443  | 		goto newpos;
444  | 	    }
445  | 	    if(!u_in_vault &&
446  | 	       (grd_in_vault ||
447  | 		(in_fcorridor(grd, grd->mx, grd->my) &&
448  | 		 !in_fcorridor(grd, u.ux, u.uy)))) {
449  | 		rloc(grd);
450  | 		wallify_vault(grd);
451  | 		(void) clear_fcorr(grd, TRUE);
452  | 		goto letknow;
453  | 	    }
454  | 	    if(!in_fcorridor(grd, grd->mx, grd->my))
455  | 		(void) clear_fcorr(grd, TRUE);
456  | 	    return(-1);
457  | 	}
458  | 	if(abs(egrd->ogx - grd->mx) > 1 ||
459  | 			abs(egrd->ogy - grd->my) > 1)
460  | 		return(-1);	/* teleported guard - treat as monster */
461  | 	if(egrd->fcend == 1) {
462  | 	    if(u_in_vault &&
463  | 			(u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
464  | 		if(egrd->warncnt == 3)
465  | 			verbalize("I repeat, %sfollow me!",
466  | 				u_carry_gold ? (!u.ugold ?
467  | 					  "drop that hidden gold and " :
468  | 					  "drop that gold and ") : "");
469  | 		if(egrd->warncnt == 7) {
470  | 			m = grd->mx;
471  | 			n = grd->my;
472  | 			verbalize("You've been warned, knave!");
473  | 			mnexto(grd);
474  | 			levl[m][n].typ = egrd->fakecorr[0].ftyp;
475  | 			newsym(m,n);
476  | 			grd->mpeaceful = 0;
477  | 			return(-1);
478  | 		}
479  | 		/* not fair to get mad when (s)he's fainted or paralyzed */
480  | 		if(!is_fainted() && multi >= 0) egrd->warncnt++;
481  | 		return(0);
482  | 	    }
483  | 
484  | 	    if (!u_in_vault) {
485  | 		if (u_carry_gold) {	/* player teleported */
486  | 		    m = grd->mx;
487  | 		    n = grd->my;
488  | 		    rloc(grd);
489  | 		    levl[m][n].typ = egrd->fakecorr[0].ftyp;
490  | 		    newsym(m,n);
491  | 		    grd->mpeaceful = 0;
492  | letknow:
493  | 		    if(!cansee(grd->mx, grd->my))
494  | 			You_hear("the shrill sound of a guard's whistle.");
495  | 		    else
496  | 			You(um_dist(grd->mx, grd->my, 2) ?
497  | 			    "see an angry %s approaching." :
498  | 			    "are confronted by an angry %s.",
499  | 			    l_monnam(grd));
500  | 		    return(-1);
501  | 		} else {
502  | 		    verbalize("Well, begone.");
503  | 		    wallify_vault(grd);
504  | 		    egrd->gddone = 1;
505  | 		    goto cleanup;
506  | 		}
507  | 	    }
508  | 	}
509  | 
510  | 	if(egrd->fcend > 1) {
511  | 	    if(egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
512  | 		  !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
513  | 		  levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
514  | 				 == egrd->fakecorr[0].ftyp) {
515  | 		pline_The("guard, confused, disappears.");
516  | 		disappear_msg_seen = TRUE;
517  | 		goto cleanup;
518  | 	    }
519  | 	    if(u_carry_gold &&
520  | 		    (in_fcorridor(grd, u.ux, u.uy) ||
521  | 		    /* cover a 'blind' spot */
522  | 		    (egrd->fcend > 1 && u_in_vault))) {
523  | 		if(!grd->mx) {
524  | 			restfakecorr(grd);
525  | 			return(-2);
526  | 		}
527  | 		if(egrd->warncnt < 6) {
528  | 			egrd->warncnt = 6;
529  | 			verbalize("Drop all your gold, scoundrel!");
530  | 			return(0);
531  | 		} else {
532  | 			verbalize("So be it, rogue!");
533  | 			grd->mpeaceful = 0;
534  | 			return(-1);
535  | 		}
536  | 	    }
537  | 	}
538  | 	for(fci = egrd->fcbeg; fci < egrd->fcend; fci++)
539  | 	    if(g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)){
540  | 		m = egrd->fakecorr[fci].fx;
541  | 		n = egrd->fakecorr[fci].fy;
542  | 		goldincorridor = TRUE;
543  | 	    }
544  | 	if(goldincorridor && !egrd->gddone) {
545  | 		x = grd->mx;
546  | 		y = grd->my;
547  | 		if (m == u.ux && n == u.uy) {
548  | 		    struct obj *gold = g_at(m,n);
549  | 		    /* Grab the gold from between the hero's feet.  */
550  | 		    grd->mgold += gold->quan;
551  | 		    delobj(gold);
552  | 		    newsym(m,n);
553  | 		} else if (m == x && n == y) {
554  | 		    mpickgold(grd);	/* does a newsym */
555  | 		} else {
556  | 		    /* just for insurance... */
557  | 		    if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
558  | 			verbalize("Out of my way, scum!");
559  | 			rloc(m_at(m, n));
560  | 		    }
561  | 		    remove_monster(grd->mx, grd->my);
562  | 		    newsym(grd->mx, grd->my);
563  | 		    place_monster(grd, m, n);
564  | 		    mpickgold(grd);	/* does a newsym */
565  | 		}
566  | 		if(cansee(m,n))
567  | 		    pline("%s%s picks up the gold.", Monnam(grd),
568  | 				grd->mpeaceful ? " calms down and" : "");
569  | 		if(x != grd->mx || y != grd->my) {
570  | 		    remove_monster(grd->mx, grd->my);
571  | 		    newsym(grd->mx, grd->my);
572  | 		    place_monster(grd, x, y);
573  | 		    newsym(x, y);
574  | 		}
575  | 		if(!grd->mpeaceful) return(-1);
576  | 		else {
577  | 		    egrd->warncnt = 5;
578  | 		    return(0);
579  | 		}
580  | 	}
581  | 	if(um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
582  | 		if(!egrd->gddone && !rn2(10)) verbalize("Move along!");
583  | 		restfakecorr(grd);
584  | 		return(0);	/* didn't move */
585  | 	}
586  | 	x = grd->mx;
587  | 	y = grd->my;
588  | 
589  | 	if(u_in_vault) goto nextpos;
590  | 
591  | 	/* look around (hor & vert only) for accessible places */
592  | 	for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
593  | 	  if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {
594  | 
595  | 	    typ = (crm = &levl[nx][ny])->typ;
596  | 	    if(!IS_STWALL(typ) && !IS_POOL(typ)) {
597  | 
598  | 		if(in_fcorridor(grd, nx, ny))
599  | 			goto nextnxy;
600  | 
601  | 		if(*in_rooms(nx,ny,VAULT))
602  | 			continue;
603  | 
604  | 		/* seems we found a good place to leave him alone */
605  | 		egrd->gddone = 1;
606  | 		if(ACCESSIBLE(typ)) goto newpos;
607  | #ifdef STUPID
608  | 		if (typ == SCORR)
609  | 		    crm->typ = CORR;
610  | 		else
611  | 		    crm->typ = DOOR;
612  | #else
613  | 		crm->typ = (typ == SCORR) ? CORR : DOOR;
614  | #endif
615  | 		if(crm->typ == DOOR) crm->doormask = D_NODOOR;
616  | 		goto proceed;
617  | 	    }
618  | 	  }
619  | nextnxy:	;
620  | 	}
621  | nextpos:
622  | 	nx = x;
623  | 	ny = y;
624  | 	gx = egrd->gdx;
625  | 	gy = egrd->gdy;
626  | 	dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
627  | 	dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
628  | 	if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
629  | 
630  | 	while((typ = (crm = &levl[nx][ny])->typ) != 0) {
631  | 	/* in view of the above we must have IS_WALL(typ) or typ == POOL */
632  | 	/* must be a wall here */
633  | 		if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) &&
634  | 		    IS_ROOM(levl[nx+nx-x][ny+ny-y].typ)){
635  | 			crm->typ = DOOR;
636  | 			crm->doormask = D_NODOOR;
637  | 			goto proceed;
638  | 		}
639  | 		if(dy && nx != x) {
640  | 			nx = x; ny = y+dy;
641  | 			continue;
642  | 		}
643  | 		if(dx && ny != y) {
644  | 			ny = y; nx = x+dx; dy = 0;
645  | 			continue;
646  | 		}
647  | 		/* I don't like this, but ... */
648  | 		if(IS_ROOM(typ)) {
649  | 			crm->typ = DOOR;
650  | 			crm->doormask = D_NODOOR;
651  | 			goto proceed;
652  | 		}
653  | 		break;
654  | 	}
655  | 	crm->typ = CORR;
656  | proceed:
657  | 	unblock_point(nx, ny);	/* doesn't block light */
658  | 	if (cansee(nx,ny))
659  | 	    newsym(nx,ny);
660  | 
661  | 	fcp = &(egrd->fakecorr[egrd->fcend]);
662  | 	if(egrd->fcend++ == FCSIZ) panic("fakecorr overflow");
663  | 	fcp->fx = nx;
664  | 	fcp->fy = ny;
665  | 	fcp->ftyp = typ;
666  | newpos:
667  | 	if(egrd->gddone) {
668  | 		/* The following is a kludge.  We need to keep    */
669  | 		/* the guard around in order to be able to make   */
670  | 		/* the fake corridor disappear as the player      */
671  | 		/* moves out of it, but we also need the guard    */
672  | 		/* out of the way.  We send the guard to never-   */
673  | 		/* never land.  We set ogx ogy to mx my in order  */
674  | 		/* to avoid a check at the top of this function.  */
675  | 		/* At the end of the process, the guard is killed */
676  | 		/* in restfakecorr().				  */
677  | cleanup:
678  | 		x = grd->mx; y = grd->my;
679  | 
680  | 		wallify_vault(grd);
681  | 		remove_monster(grd->mx, grd->my);
682  | 		newsym(grd->mx,grd->my);
683  | 		place_monster(grd, 0, 0);
684  | 		egrd->ogx = grd->mx;
685  | 		egrd->ogy = grd->my;
686  | 		restfakecorr(grd);
687  | 		if(!semi_dead && (in_fcorridor(grd, u.ux, u.uy) ||
688  | 				     cansee(x, y))) {
689  | 		    if (!disappear_msg_seen)
690  | 			pline("Suddenly, the guard disappears.");
691  | 		    return(1);
692  | 		}
693  | 		return(-2);
694  | 	}
695  | 	egrd->ogx = grd->mx;	/* update old positions */
696  | 	egrd->ogy = grd->my;
697  | 	remove_monster(grd->mx, grd->my);
698  | 	place_monster(grd, nx, ny);
699  | 	newsym(grd->mx,grd->my);
700  | 	restfakecorr(grd);
701  | 	return(1);
702  | }
703  | 
704  | /* Routine when dying or quitting with a vault guard around */
705  | void
706  | paygd()
707  | {
708  | 	register struct monst *grd = findgd();
709  | 	struct obj *gold;
710  | 	int gx,gy;
711  | 	char buf[BUFSZ];
712  | 
713  | 	if (!u.ugold || !grd) return;
714  | 
715  | 	if (u.uinvault) {
716  | 	    Your("%ld zorkmid%s goes into the Magic Memory Vault.",
717  | 		u.ugold, plur(u.ugold));
718  | 	    gx = u.ux;
719  | 	    gy = u.uy;
720  | 	} else {
721  | 	    if(grd->mpeaceful) { /* guard has no "right" to your gold */
722  | 		mongone(grd);
723  | 		return;
724  | 	    }
725  | 	    mnexto(grd);
726  | 	    pline("%s remits your gold to the vault.", Monnam(grd));
727  | 	    gx = rooms[EGD(grd)->vroom].lx + rn2(2);
728  | 	    gy = rooms[EGD(grd)->vroom].ly + rn2(2);
729  | 	    Sprintf(buf,
730  | 		"To Croesus: here's the gold recovered from %s the %s.",
731  | 		plname, mons[u.umonster].mname);
732  | 	    make_grave(gx, gy, buf);
733  | 	}
734  | 	place_object(gold = mkgoldobj(u.ugold), gx, gy);
735  | 	stackobj(gold);
736  | 	mongone(grd);
737  | }
738  | 
739  | long
740  | hidden_gold()
741  | {
742  | 	register long value = 0L;
743  | 	register struct obj *obj;
744  | 
745  | 	for (obj = invent; obj; obj = obj->nobj)
746  | 	    if (Has_contents(obj))
747  | 		value += contained_gold(obj);
748  | 	/* unknown gold stuck inside statues may cause some consternation... */
749  | 
750  | 	return(value);
751  | }
752  | 
753  | boolean
754  | gd_sound()  /* prevent "You hear footsteps.." when inappropriate */
755  | {
756  | 	register struct monst *grd = findgd();
757  | 
758  | 	if (vault_occupied(u.urooms)) return(FALSE);
759  | 	else return((boolean)(grd == (struct monst *)0));
760  | }
761  | 
762  | #endif /* OVLB */
763  | 
764  | /*vault.c*/