OSDN Git Service

add gitignore
[nethackexpress/trunk.git] / src / vault.c
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
8 STATIC_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
15 STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *,BOOLEAN_P));
16 STATIC_DCL void FDECL(restfakecorr,(struct monst *));
17 STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *,int,int));
18 STATIC_DCL void FDECL(move_gold,(struct obj *,int));
19 STATIC_DCL void FDECL(wallify_vault,(struct monst *));
20
21 STATIC_OVL boolean
22 clear_fcorr(grd, forceshow)
23 register struct monst *grd;
24 register 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
62 STATIC_OVL void
63 restfakecorr(grd)
64 register 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
70 boolean
71 grddead(grd)                            /* called in mon.c */
72 register 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
88 STATIC_OVL boolean
89 in_fcorridor(grd, x, y)
90 register struct monst *grd;
91 int 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
102 STATIC_OVL
103 struct monst *
104 findgd()
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
117 char
118 vault_occupied(array)
119 char *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
129 void
130 invault()
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           }
174 incr_radius: ;
175         }
176         impossible("Not a single corridor on this level??");
177         tele();
178         return;
179 fnd:
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
352 STATIC_OVL void
353 move_gold(gold, vroom)
354 struct obj *gold;
355 int 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
368 STATIC_OVL void
369 wallify_vault(grd)
370 struct 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  */
436 int
437 gd_move(grd)
438 register 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;
522 letknow:
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           }
654 nextnxy:        ;
655         }
656 nextpos:
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;
691 proceed:
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;
701 newpos:
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().                             */
712 cleanup:
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 */
741 void
742 paygd()
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
801 long
802 hidden_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
815 boolean
816 gd_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*/