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