OSDN Git Service

upgrade to 3.6.1
[jnethack/source.git] / src / vault.c
1 /* NetHack 3.6  vault.c $NHDT-Date: 1452132199 2016/01/07 02:03:19 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.42 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 STATIC_DCL struct monst *NDECL(findgd);
14
15 STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *, BOOLEAN_P));
16 STATIC_DCL void FDECL(blackout, (int, int));
17 STATIC_DCL void FDECL(restfakecorr, (struct monst *));
18 STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *, int, int));
19 STATIC_DCL void FDECL(move_gold, (struct obj *, int));
20 STATIC_DCL void FDECL(wallify_vault, (struct monst *));
21
22 void
23 newegd(mtmp)
24 struct monst *mtmp;
25 {
26     if (!mtmp->mextra)
27         mtmp->mextra = newmextra();
28     if (!EGD(mtmp)) {
29         EGD(mtmp) = (struct egd *) alloc(sizeof(struct egd));
30         (void) memset((genericptr_t) EGD(mtmp), 0, sizeof(struct egd));
31     }
32 }
33
34 void
35 free_egd(mtmp)
36 struct monst *mtmp;
37 {
38     if (mtmp->mextra && EGD(mtmp)) {
39         free((genericptr_t) EGD(mtmp));
40         EGD(mtmp) = (struct egd *) 0;
41     }
42     mtmp->isgd = 0;
43 }
44
45 STATIC_OVL boolean
46 clear_fcorr(grd, forceshow)
47 struct monst *grd;
48 boolean forceshow;
49 {
50     register int fcx, fcy, fcbeg;
51     struct monst *mtmp;
52     boolean sawcorridor = FALSE;
53     struct egd *egrd = EGD(grd);
54     struct trap *trap;
55     struct rm *lev;
56
57     if (!on_level(&egrd->gdlevel, &u.uz))
58         return TRUE;
59
60     while ((fcbeg = egrd->fcbeg) < egrd->fcend) {
61         fcx = egrd->fakecorr[fcbeg].fx;
62         fcy = egrd->fakecorr[fcbeg].fy;
63         if ((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) && egrd->gddone)
64             forceshow = TRUE;
65         if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
66             || (!forceshow && couldsee(fcx, fcy))
67             || (Punished && !carried(uball) && uball->ox == fcx
68                 && uball->oy == fcy))
69             return FALSE;
70
71         if ((mtmp = m_at(fcx, fcy)) != 0) {
72             if (mtmp->isgd) {
73                 return FALSE;
74             } else if (!in_fcorridor(grd, u.ux, u.uy)) {
75                 if (mtmp->mtame)
76                     yelp(mtmp);
77                 (void) rloc(mtmp, FALSE);
78             }
79         }
80         lev = &levl[fcx][fcy];
81         if (lev->typ == CORR && cansee(fcx, fcy))
82             sawcorridor = TRUE;
83         lev->typ = egrd->fakecorr[fcbeg].ftyp;
84         if (IS_STWALL(lev->typ)) {
85             /* destroy any trap here (pit dug by you, hole dug via
86                wand while levitating or by monster, bear trap or land
87                mine via object, spun web) when spot reverts to stone */
88             if ((trap = t_at(fcx, fcy)) != 0)
89                 deltrap(trap);
90             /* undo scroll/wand/spell of light affecting this spot */
91             if (lev->typ == STONE)
92                 blackout(fcx, fcy);
93         }
94         map_location(fcx, fcy, 1); /* bypass vision */
95         if (!ACCESSIBLE(lev->typ))
96             block_point(fcx, fcy);
97         vision_full_recalc = 1;
98         egrd->fcbeg++;
99     }
100     if (sawcorridor)
101 /*JP
102         pline_The("corridor disappears.");
103 */
104         pline("\92Ê\98H\82Í\8fÁ\82¦\82½\81D");
105     if (IS_ROCK(levl[u.ux][u.uy].typ))
106 /*JP
107         You("are encased in rock.");
108 */
109         You("\90Î\82É\82Â\82Â\82Ü\82ê\82½\81D");
110     return TRUE;
111 }
112
113 /* as a temporary corridor is removed, set stone locations and adjacent
114    spots to unlit; if player used scroll/wand/spell of light while inside
115    the corridor, we don't want the light to reappear if/when a new tunnel
116    goes through the same area */
117 STATIC_OVL void
118 blackout(x, y)
119 int x, y;
120 {
121     struct rm *lev;
122     int i, j;
123
124     for (i = x - 1; i <= x + 1; ++i)
125         for (j = y - 1; j <= y + 1; ++j) {
126             if (!isok(i, j))
127                 continue;
128             lev = &levl[i][j];
129             /* [possible bug: when (i != x || j != y), perhaps we ought
130                to check whether the spot on the far side is lit instead
131                of doing a blanket blackout of adjacent locations] */
132             if (lev->typ == STONE)
133                 lev->lit = lev->waslit = 0;
134             /* mark <i,j> as not having been seen from <x,y> */
135             unset_seenv(lev, x, y, i, j);
136         }
137 }
138
139 STATIC_OVL void
140 restfakecorr(grd)
141 struct monst *grd;
142 {
143     /* it seems you left the corridor - let the guard disappear */
144     if (clear_fcorr(grd, FALSE)) {
145         grd->isgd = 0; /* dmonsfree() should delete this mon */
146         mongone(grd);
147     }
148 }
149
150 /* called in mon.c */
151 boolean
152 grddead(grd)
153 struct monst *grd;
154 {
155     boolean dispose = clear_fcorr(grd, TRUE);
156
157     if (!dispose) {
158         /* destroy guard's gold; drop any other inventory */
159         relobj(grd, 0, FALSE);
160         /* guard is dead; monster traversal loops should skip it */
161         grd->mhp = 0;
162         if (grd == context.polearm.hitmon)
163             context.polearm.hitmon = 0;
164         /* see comment by newpos in gd_move() */
165         remove_monster(grd->mx, grd->my);
166         newsym(grd->mx, grd->my);
167         place_monster(grd, 0, 0);
168         EGD(grd)->ogx = grd->mx;
169         EGD(grd)->ogy = grd->my;
170         dispose = clear_fcorr(grd, TRUE);
171     }
172     if (dispose)
173         grd->isgd = 0; /* for dmonsfree() */
174     return dispose;
175 }
176
177 STATIC_OVL boolean
178 in_fcorridor(grd, x, y)
179 struct monst *grd;
180 int x, y;
181 {
182     register int fci;
183     struct egd *egrd = EGD(grd);
184
185     for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
186         if (x == egrd->fakecorr[fci].fx && y == egrd->fakecorr[fci].fy)
187             return TRUE;
188     return FALSE;
189 }
190
191 STATIC_OVL
192 struct monst *
193 findgd()
194 {
195     register struct monst *mtmp;
196
197     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
198         if (DEADMONSTER(mtmp))
199             continue;
200         if (mtmp->isgd && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
201             return mtmp;
202     }
203     return (struct monst *) 0;
204 }
205
206 void
207 vault_summon_gd()
208 {
209     if (vault_occupied(u.urooms) && !findgd())
210         u.uinvault = (VAULT_GUARD_TIME - 1);
211 }
212
213 char
214 vault_occupied(array)
215 char *array;
216 {
217     register char *ptr;
218
219     for (ptr = array; *ptr; ptr++)
220         if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
221             return *ptr;
222     return '\0';
223 }
224
225 void
226 invault()
227 {
228 #ifdef BSD_43_BUG
229     int dummy; /* hack to avoid schain botch */
230 #endif
231     struct monst *guard;
232     boolean gsensed;
233     int trycount, vaultroom = (int) vault_occupied(u.urooms);
234
235     if (!vaultroom) {
236         u.uinvault = 0;
237         return;
238     }
239
240     vaultroom -= ROOMOFFSET;
241
242     guard = findgd();
243     if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) {
244         /* if time ok and no guard now. */
245         char buf[BUFSZ] = DUMMY;
246         register int x, y, dd, gx, gy;
247         int lx = 0, ly = 0;
248         long umoney;
249
250         /* first find the goal for the guard */
251         for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
252             for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) {
253                 if (y < 0 || y > ROWNO - 1)
254                     continue;
255                 for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) {
256                     if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
257                         x = u.ux + dd;
258                     if (x < 1 || x > COLNO - 1)
259                         continue;
260                     if (levl[x][y].typ == CORR) {
261                         if (x < u.ux)
262                             lx = x + 1;
263                         else if (x > u.ux)
264                             lx = x - 1;
265                         else
266                             lx = x;
267                         if (y < u.uy)
268                             ly = y + 1;
269                         else if (y > u.uy)
270                             ly = y - 1;
271                         else
272                             ly = y;
273                         if (levl[lx][ly].typ != STONE
274                             && levl[lx][ly].typ != CORR)
275                             goto incr_radius;
276                         goto fnd;
277                     }
278                 }
279             }
280         incr_radius:
281             ;
282         }
283         impossible("Not a single corridor on this level??");
284         tele();
285         return;
286     fnd:
287         gx = x;
288         gy = y;
289
290         /* next find a good place for a door in the wall */
291         x = u.ux;
292         y = u.uy;
293         if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */
294             if (levl[x + 1][y].typ == ROOM)
295                 x = x + 1;
296             else if (levl[x][y + 1].typ == ROOM)
297                 y = y + 1;
298             else if (levl[x - 1][y].typ == ROOM)
299                 x = x - 1;
300             else if (levl[x][y - 1].typ == ROOM)
301                 y = y - 1;
302             else if (levl[x + 1][y + 1].typ == ROOM) {
303                 x = x + 1;
304                 y = y + 1;
305             } else if (levl[x - 1][y - 1].typ == ROOM) {
306                 x = x - 1;
307                 y = y - 1;
308             } else if (levl[x + 1][y - 1].typ == ROOM) {
309                 x = x + 1;
310                 y = y - 1;
311             } else if (levl[x - 1][y + 1].typ == ROOM) {
312                 x = x - 1;
313                 y = y + 1;
314             }
315         }
316         while (levl[x][y].typ == ROOM) {
317             register int dx, dy;
318
319             dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
320             dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
321             if (abs(gx - x) >= abs(gy - y))
322                 x += dx;
323             else
324                 y += dy;
325         }
326         if (x == u.ux && y == u.uy) {
327             if (levl[x + 1][y].typ == HWALL || levl[x + 1][y].typ == DOOR)
328                 x = x + 1;
329             else if (levl[x - 1][y].typ == HWALL
330                      || levl[x - 1][y].typ == DOOR)
331                 x = x - 1;
332             else if (levl[x][y + 1].typ == VWALL
333                      || levl[x][y + 1].typ == DOOR)
334                 y = y + 1;
335             else if (levl[x][y - 1].typ == VWALL
336                      || levl[x][y - 1].typ == DOOR)
337                 y = y - 1;
338             else
339                 return;
340         }
341
342         /* make something interesting happen */
343         if (!(guard = makemon(&mons[PM_GUARD], x, y, MM_EGD)))
344             return;
345         guard->isgd = 1;
346         guard->mpeaceful = 1;
347         set_malign(guard);
348         EGD(guard)->gddone = 0;
349         EGD(guard)->ogx = x;
350         EGD(guard)->ogy = y;
351         assign_level(&(EGD(guard)->gdlevel), &u.uz);
352         EGD(guard)->vroom = vaultroom;
353         EGD(guard)->warncnt = 0;
354
355         reset_faint(); /* if fainted - wake up */
356         gsensed = !canspotmon(guard);
357         if (!gsensed)
358 #if 0 /*JP*/
359             pline("Suddenly one of the Vault's %s enters!",
360                   makeplural(guard->data->mname));
361 #else
362             pline("\93Ë\91R\81C\91q\8cÉ\82Ì\94Ô\95º\82ª\93ü\82Á\82Ä\82«\82½\81I");
363 #endif
364         else
365 /*JP
366             pline("Someone else has entered the Vault.");
367 */
368             pline("\92N\82©\82ª\91q\8cÉ\82É\93ü\82Á\82Ä\82«\82½\81D");
369         newsym(guard->mx, guard->my);
370         if (u.uswallow) {
371             /* can't interrogate hero, don't interrogate engulfer */
372 /*JP
373             if (!Deaf) verbalize("What's going on here?");
374 */
375             if (!Deaf) verbalize("\82±\82±\82Å\89½\82ð\82µ\82Ä\82¢\82é\82ñ\82¾\81H");
376             if (gsensed)
377 /*JP
378                 pline_The("other presence vanishes.");
379 */
380                 pline("\91¼\90l\82Ì\8bC\94z\82Í\8fÁ\82¦\82½\81D");
381             mongone(guard);
382             return;
383         }
384         if (youmonst.m_ap_type == M_AP_OBJECT || u.uundetected) {
385             if (youmonst.m_ap_type == M_AP_OBJECT
386                 && youmonst.mappearance != GOLD_PIECE)
387 #if 0 /*JP*/
388                 if (!Deaf) verbalize("Hey! Who left that %s in here?",
389                                     mimic_obj_name(&youmonst));
390 #else
391                 if (!Deaf) verbalize("\82¨\82¢\81I\82¾\82ê\82ª\82±\82Ì%s\82ð\82±\82±\82É\92u\82¢\82Ä\8ds\82Á\82½\82ñ\82¾\81H",
392                                     mimic_obj_name(&youmonst));
393 #endif
394             /* You're mimicking some object or you're hidden. */
395 /*JP
396             pline("Puzzled, %s turns around and leaves.", mhe(guard));
397 */
398             pline("%s\82Í\8d¢\98f\82µ\82È\82ª\82ç\81C\8cü\82«\92¼\82Á\82Ä\8b\8e\82Á\82Ä\82¢\82Á\82½\81D", mhe(guard));
399             mongone(guard);
400             return;
401         }
402         if (Strangled || is_silent(youmonst.data) || multi < 0) {
403             /* [we ought to record whether this this message has already
404                been given in order to vary it upon repeat visits, but
405                discarding the monster and its egd data renders that hard] */
406             if (Deaf)
407                 pline("%s huffs and turns to leave.", noit_Monnam(guard));
408             else
409 /*JP
410             verbalize("I'll be back when you're ready to speak to me!");
411 */
412             verbalize("\98b\82¹\82é\82æ\82¤\82É\82È\82Á\82½\82ç\96ß\82Á\82Ä\82«\82Ä\82â\82é\81I");
413             mongone(guard);
414             return;
415         }
416
417         stop_occupation(); /* if occupied, stop it *now* */
418         if (multi > 0) {
419             nomul(0);
420             unmul((char *) 0);
421         }
422         trycount = 5;
423         do {
424 #if 0 /*JP*/
425             getlin(Deaf ? "You are required to supply your name. -"
426                         : "\"Hello stranger, who are you?\" -", buf);
427 #else
428             getlin(Deaf ? "\96¼\91O\82ð\8c¾\82¤\82æ\82¤\82É\8b\81\82ß\82ç\82ê\82½\81D-"
429                         : "\81u\8c©\82È\82¢\8aç\82¾\82È\81C\82¨\82Ü\82¦\82Í\92N\82¾\81H\81v-", buf);
430 #endif
431             (void) mungspaces(buf);
432 #if 0 /*JP*/
433         } while (!buf[0] && --trycount > 0);
434 #else
435         } while (!buf[0] && !is_kanji(buf[0]) && --trycount > 0);
436 #endif
437
438         if (u.ualign.type == A_LAWFUL
439             /* ignore trailing text, in case player includes rank */
440             && strncmpi(buf, plname, (int) strlen(plname)) != 0) {
441             adjalign(-1); /* Liar! */
442         }
443
444 #if 0 /*JP*/
445         if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
446             || !strcmpi(buf, "Creosote")) {
447 #else
448     if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
449         || !strcmpi(buf, "Creosote")
450         || !strcmp(buf, "\83N\83\8d\83C\83\\83X") || !strcmp(buf, "\83N\83\8c\83I\83\\81[\83g")) {
451 #endif
452             if (!mvitals[PM_CROESUS].died) {
453                 if (Deaf) {
454                     if (!Blind)
455                         pline("%s waves goodbye.", noit_Monnam(guard));
456                 } else {
457                     verbalize(
458 /*JP
459                     "Oh, yes, of course.  Sorry to have disturbed you.");
460 */
461                     "\82¢\82â\81C\82±\82è\82á\81C\82¦\81[\82Æ\81C\82¨\91\9b\82ª\82¹\82µ\82Ü\82µ\82½\81D");
462                 }
463                 mongone(guard);
464             } else {
465                 setmangry(guard, FALSE);
466                 if (Deaf) {
467                    if (!Blind)
468                         pline("%s mouths something and looks very angry!",
469                               noit_Monnam(guard));
470                 } else {
471 #if 0 /*JP:T*/
472                    verbalize(
473                            "Back from the dead, are you?  I'll remedy that!");
474 #else
475                    verbalize(
476                            "\82Ù\82¤\81I\8e\80\82Ì\90¢\8aE\82©\82ç\96ß\82Á\82Ä\82«\82½\82Ì\82©\81H\82¤\82»\82È\82ç\8fã\8eè\82É\82Â\82¯\81I");
477 #endif
478                 }
479                 /* don't want guard to waste next turn wielding a weapon */
480                 if (!MON_WEP(guard)) {
481                     guard->weapon_check = NEED_HTH_WEAPON;
482                     (void) mon_wield_item(guard);
483                 }
484             }
485             return;
486         }
487         if (Deaf)
488             pline("%s doesn't %srecognize you.", noit_Monnam(guard),
489                     (Blind) ? "" : "appear to ");
490         else
491 /*JP
492         verbalize("I don't know you.");
493 */
494         verbalize("\92m\82ç\82ñ\82È\81D");
495         umoney = money_cnt(invent);
496         if (!umoney && !hidden_gold()) {
497             if (Deaf)
498                 pline("%s stomps%s.", noit_Monnam(guard),
499                       (Blind) ? "" : " and beckons");
500             else
501 /*JP
502             verbalize("Please follow me.");
503 */
504             verbalize("\8e\84\82Ì\8cã\82É\82Â\82¢\82Ä\82«\82È\82³\82¢\81D");
505         } else {
506             if (!umoney) {
507                 if (Deaf) {
508                     if (!Blind)
509                         pline("%s glares at you%s.", noit_Monnam(guard),
510                               invent ? "r stuff" : "");
511                 } else {
512 /*JP
513                 verbalize("You have hidden gold.");
514 */
515                 verbalize("\82Ü\82¾\8bà\89Ý\82ð\89B\82µ\82Ä\82é\82È\81D");
516                 }
517             }
518             if (Deaf) {
519                 if (!Blind)
520                     pline(
521                        "%s holds out %s palm and beckons with %s other hand.",
522                           noit_Monnam(guard), mhis(guard), mhis(guard));
523             } else {
524                 verbalize(
525 /*JP
526                 "Most likely all your gold was stolen from this vault.");
527 */
528                 "\91q\8cÉ\82©\82ç\93\90\82ñ\82¾\8bà\89Ý\82ª\82 \82é\82¾\82ë\82¤\81D");
529 /*JP
530             verbalize("Please drop that gold and follow me.");
531 */
532             verbalize("\82»\82ê\82ð\82»\82Á\82­\82è\96ß\82µ\82Ä\82©\82ç\81C\8e\84\82Ì\8cã\82É\82Â\82¢\82Ä\82«\82È\82³\82¢\81D");
533             }
534         }
535         EGD(guard)->gdx = gx;
536         EGD(guard)->gdy = gy;
537         EGD(guard)->fcbeg = 0;
538         EGD(guard)->fakecorr[0].fx = x;
539         EGD(guard)->fakecorr[0].fy = y;
540         if (IS_WALL(levl[x][y].typ))
541             EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
542         else { /* the initial guard location is a dug door */
543             int vlt = EGD(guard)->vroom;
544             xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
545             xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
546
547             if (x == lowx - 1 && y == lowy - 1)
548                 EGD(guard)->fakecorr[0].ftyp = TLCORNER;
549             else if (x == hix + 1 && y == lowy - 1)
550                 EGD(guard)->fakecorr[0].ftyp = TRCORNER;
551             else if (x == lowx - 1 && y == hiy + 1)
552                 EGD(guard)->fakecorr[0].ftyp = BLCORNER;
553             else if (x == hix + 1 && y == hiy + 1)
554                 EGD(guard)->fakecorr[0].ftyp = BRCORNER;
555             else if (y == lowy - 1 || y == hiy + 1)
556                 EGD(guard)->fakecorr[0].ftyp = HWALL;
557             else if (x == lowx - 1 || x == hix + 1)
558                 EGD(guard)->fakecorr[0].ftyp = VWALL;
559         }
560         levl[x][y].typ = DOOR;
561         levl[x][y].doormask = D_NODOOR;
562         unblock_point(x, y); /* doesn't block light */
563         EGD(guard)->fcend = 1;
564         EGD(guard)->warncnt = 1;
565     }
566 }
567
568 STATIC_OVL void
569 move_gold(gold, vroom)
570 struct obj *gold;
571 int vroom;
572 {
573     xchar nx, ny;
574
575     remove_object(gold);
576     newsym(gold->ox, gold->oy);
577     nx = rooms[vroom].lx + rn2(2);
578     ny = rooms[vroom].ly + rn2(2);
579     place_object(gold, nx, ny);
580     stackobj(gold);
581     newsym(nx, ny);
582 }
583
584 STATIC_OVL void
585 wallify_vault(grd)
586 struct monst *grd;
587 {
588     int x, y, typ;
589     int vlt = EGD(grd)->vroom;
590     char tmp_viz;
591     xchar lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1,
592           loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1;
593     struct monst *mon;
594     struct obj *gold;
595     struct trap *trap;
596     boolean fixed = FALSE;
597     boolean movedgold = FALSE;
598
599     for (x = lox; x <= hix; x++)
600         for (y = loy; y <= hiy; y++) {
601             /* if not on the room boundary, skip ahead */
602             if (x != lox && x != hix && y != loy && y != hiy)
603                 continue;
604
605             if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
606                 if ((mon = m_at(x, y)) != 0 && mon != grd) {
607                     if (mon->mtame)
608                         yelp(mon);
609                     (void) rloc(mon, FALSE);
610                 }
611                 if ((gold = g_at(x, y)) != 0) {
612                     move_gold(gold, EGD(grd)->vroom);
613                     movedgold = TRUE;
614                 }
615                 if ((trap = t_at(x, y)) != 0)
616                     deltrap(trap);
617                 if (x == lox)
618                     typ =
619                         (y == loy) ? TLCORNER : (y == hiy) ? BLCORNER : VWALL;
620                 else if (x == hix)
621                     typ =
622                         (y == loy) ? TRCORNER : (y == hiy) ? BRCORNER : VWALL;
623                 else /* not left or right side, must be top or bottom */
624                     typ = HWALL;
625                 levl[x][y].typ = typ;
626                 levl[x][y].doormask = 0;
627                 /*
628                  * hack: player knows walls are restored because of the
629                  * message, below, so show this on the screen.
630                  */
631                 tmp_viz = viz_array[y][x];
632                 viz_array[y][x] = IN_SIGHT | COULD_SEE;
633                 newsym(x, y);
634                 viz_array[y][x] = tmp_viz;
635                 block_point(x, y);
636                 fixed = TRUE;
637             }
638         }
639
640     if (movedgold || fixed) {
641         if (in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
642 /*JP
643             pline("%s whispers an incantation.", noit_Monnam(grd));
644 */
645             pline("%s\82Í\8eô\95\82ð\82³\82³\82â\82¢\82½\81D", noit_Monnam(grd));
646         else
647 /*JP
648             You_hear("a distant chant.");
649 */
650             You_hear("\89\93\95û\82Å\82Ì\8eô\95\82ð\95·\82¢\82½\81D");
651         if (movedgold)
652 /*JP
653             pline("A mysterious force moves the gold into the vault.");
654 */
655             pline("\95s\8ev\8bc\82È\97Í\82ª\8bà\89Ý\82ð\91q\8cÉ\82Ö\89^\82ñ\82¾\81D");
656         if (fixed)
657 /*JP
658             pline_The("damaged vault's walls are magically restored!");
659 */
660             pline("\8f\9d\82Â\82¢\82½\91q\8cÉ\82Ì\95Ç\82Í\96\82\96@\82Å\95\9c\8c³\82³\82ê\82½\81I");
661     }
662 }
663
664 /*
665  * return  1: guard moved,  0: guard didn't,  -1: let m_move do it,  -2: died
666  */
667 int
668 gd_move(grd)
669 register struct monst *grd;
670 {
671     int x, y, nx, ny, m, n;
672     int dx, dy, gx, gy, fci;
673     uchar typ;
674     struct fakecorridor *fcp;
675     register struct egd *egrd = EGD(grd);
676     struct rm *crm;
677     boolean goldincorridor = FALSE,
678             u_in_vault = vault_occupied(u.urooms) ? TRUE : FALSE,
679             grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? TRUE : FALSE;
680     boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
681     long umoney = money_cnt(invent);
682     register boolean u_carry_gold = ((umoney + hidden_gold()) > 0L);
683     boolean see_guard, newspot = FALSE;
684
685     if (!on_level(&(egrd->gdlevel), &u.uz))
686         return -1;
687     nx = ny = m = n = 0;
688     if (!u_in_vault && !grd_in_vault)
689         wallify_vault(grd);
690     if (!grd->mpeaceful) {
691         if (semi_dead) {
692             egrd->gddone = 1;
693             goto newpos;
694         }
695         if (!u_in_vault
696             && (grd_in_vault || (in_fcorridor(grd, grd->mx, grd->my)
697                                  && !in_fcorridor(grd, u.ux, u.uy)))) {
698             (void) rloc(grd, FALSE);
699             wallify_vault(grd);
700             (void) clear_fcorr(grd, TRUE);
701             goto letknow;
702         }
703         if (!in_fcorridor(grd, grd->mx, grd->my))
704             (void) clear_fcorr(grd, TRUE);
705         return -1;
706     }
707     if (abs(egrd->ogx - grd->mx) > 1 || abs(egrd->ogy - grd->my) > 1)
708         return -1; /* teleported guard - treat as monster */
709
710     if (egrd->witness) {
711         if (!Deaf)
712 #if 0 /*JP*/
713             verbalize("How dare you %s that gold, scoundrel!",
714                       (egrd->witness & GD_EATGOLD) ? "consume" : "destroy");
715 #else
716             verbalize("\82æ\82­\82à\82Ü\82 \8bà\82ð%s\82à\82Ì\82¾\81C\88«\93}\82ß\81I",
717                       (egrd->witness & GD_EATGOLD) ? "\8eg\82Á\82½" : "\89ó\82µ\82½");
718 #endif
719         egrd->witness = 0;
720         grd->mpeaceful = 0;
721         return -1;
722     }
723     if (egrd->fcend == 1) {
724         if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
725             if (egrd->warncnt == 3 && !Deaf)
726 #if 0 /*JP*/
727                 verbalize("I repeat, %sfollow me!",
728                           u_carry_gold
729                               ? (!umoney ? "drop that hidden money and "
730                                          : "drop that money and ")
731                               : "");
732 #else
733                 verbalize("\8cJ\82è\95Ô\82·\81I%s\8e\84\82É\82Â\82¢\82Ä\82±\82¢\81I",
734                           u_carry_gold
735                               ? (!umoney ? "\89B\82µ\8e\9d\82Á\82Ä\82é\8bà\82ð\92u\82¢\82Ä"
736                                          : "\8bà\82ð\92u\82¢\82Ä")
737                               : "");
738 #endif
739             if (egrd->warncnt == 7) {
740                 m = grd->mx;
741                 n = grd->my;
742                 if (!Deaf)
743 /*JP
744                     verbalize("You've been warned, knave!");
745 */
746                     verbalize("\8cx\8d\90\82Í\82µ\82½\82¼\81C\88«\93}\82ß\81I");
747                 mnexto(grd);
748                 levl[m][n].typ = egrd->fakecorr[0].ftyp;
749                 newsym(m, n);
750                 grd->mpeaceful = 0;
751                 return -1;
752             }
753             /* not fair to get mad when (s)he's fainted or paralyzed */
754             if (!is_fainted() && multi >= 0)
755                 egrd->warncnt++;
756             return 0;
757         }
758
759         if (!u_in_vault) {
760             if (u_carry_gold) { /* player teleported */
761                 m = grd->mx;
762                 n = grd->my;
763                 (void) rloc(grd, TRUE);
764                 levl[m][n].typ = egrd->fakecorr[0].ftyp;
765                 newsym(m, n);
766                 grd->mpeaceful = 0;
767             letknow:
768                 if (!cansee(grd->mx, grd->my) || !mon_visible(grd))
769 /*JP
770                     You_hear("the shrill sound of a guard's whistle.");
771 */
772                     You_hear("\94Ô\95º\82Ì\89s\82¢\93J\82Ì\89¹\82ð\95·\82¢\82½\81D");
773                 else
774 #if 0 /*JP*/
775                     You(um_dist(grd->mx, grd->my, 2)
776                             ? "see %s approaching."
777                             : "are confronted by %s.",
778                         /* "an angry guard" */
779                         x_monnam(grd, ARTICLE_A, "angry", 0, FALSE));
780 #else
781                     You(um_dist(grd->mx, grd->my, 2)
782                         ? "%s\82ª\8bß\82Ã\82¢\82Ä\82­\82é\82Ì\82ð\8c©\82½\81D"
783                         : "%s\82Æ\91Î\9b³\82µ\82½\81D",
784                         x_monnam(grd, ARTICLE_A, "\93{\82Á\82½", 0, FALSE));
785 #endif
786                 return -1;
787             } else {
788                 if (!Deaf)
789 /*JP
790                     verbalize("Well, begone.");
791 */
792                     verbalize("\97§\82¿\8b\8e\82ê\81D");
793                 wallify_vault(grd);
794                 egrd->gddone = 1;
795                 goto cleanup;
796             }
797         }
798     }
799
800     if (egrd->fcend > 1) {
801         if (egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my)
802             && !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy)
803             && levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
804                    == egrd->fakecorr[0].ftyp) {
805 /*JP
806             pline("%s, confused, disappears.", noit_Monnam(grd));
807 */
808             pline("%s\82Í\8d¬\97\90\82µ\81C\8fÁ\82¦\82½\81D", noit_Monnam(grd));
809             disappear_msg_seen = TRUE;
810             goto cleanup;
811         }
812         if (u_carry_gold && (in_fcorridor(grd, u.ux, u.uy)
813                              /* cover a 'blind' spot */
814                              || (egrd->fcend > 1 && u_in_vault))) {
815             if (!grd->mx) {
816                 restfakecorr(grd);
817                 return -2;
818             }
819             if (egrd->warncnt < 6) {
820                 egrd->warncnt = 6;
821                 if (Deaf) {
822                     if (!Blind)
823                         pline("%s holds out %s palm demandingly!",
824                               noit_Monnam(grd), mhis(grd));
825                 } else {
826 /*JP
827                     verbalize("Drop all your gold, scoundrel!");
828 */
829                     verbalize("\8bà\82ð\91S\95\94\92u\82¢\82Ä\82ä\82¯\81C\82È\82ç\82¸\82à\82Ì\81I");
830                 }
831                 return 0;
832             } else {
833                 if (Deaf) {
834                     if (!Blind)
835                         pline("%s rubs %s hands with enraged delight!",
836                               noit_Monnam(grd), mhis(grd));
837                 } else {
838 /*JP
839                     verbalize("So be it, rogue!");
840 */
841                     verbalize("\93\90\90l\82ß\81I");
842                 }
843                 grd->mpeaceful = 0;
844                 return -1;
845             }
846         }
847     }
848     for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
849         if (g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) {
850             m = egrd->fakecorr[fci].fx;
851             n = egrd->fakecorr[fci].fy;
852             goldincorridor = TRUE;
853         }
854     if (goldincorridor && !egrd->gddone) {
855         x = grd->mx;
856         y = grd->my;
857         if (m == u.ux && n == u.uy) {
858             struct obj *gold = g_at(m, n);
859             /* Grab the gold from between the hero's feet.  */
860             obj_extract_self(gold);
861             add_to_minv(grd, gold);
862             newsym(m, n);
863         } else if (m == x && n == y) {
864             mpickgold(grd); /* does a newsym */
865         } else {
866             /* just for insurance... */
867             if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
868                 if (!Deaf)
869 /*JP
870                     verbalize("Out of my way, scum!");
871 */
872                     verbalize("\96Ú\82Ì\91O\82©\82ç\8fÁ\82¦\82ë\81C\83N\83\\82Á\82½\82ê\81I");
873                 (void) rloc(m_at(m, n), FALSE);
874             }
875             remove_monster(grd->mx, grd->my);
876             newsym(grd->mx, grd->my);
877             place_monster(grd, m, n);
878             mpickgold(grd); /* does a newsym */
879         }
880         if (cansee(m, n))
881 #if 0 /*JP*/
882             pline("%s%s picks up the gold.", Monnam(grd),
883                   grd->mpeaceful ? " calms down and" : "");
884 #else
885             pline("%s\82Í%s\8bà\89Ý\82ð\8fE\82Á\82½\81D", Monnam(grd),
886                   grd->mpeaceful ? "\93{\82è\82ð\90Ã\82ß" : "");
887 #endif
888         if (x != grd->mx || y != grd->my) {
889             remove_monster(grd->mx, grd->my);
890             newsym(grd->mx, grd->my);
891             place_monster(grd, x, y);
892             newsym(x, y);
893         }
894         if (!grd->mpeaceful)
895             return -1;
896         egrd->warncnt = 5;
897         return 0;
898     }
899     if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
900         if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow
901             && !(u.ustuck && !sticks(youmonst.data)))
902 /*JP
903             verbalize("Move along!");
904 */
905             verbalize("\97£\82ê\82é\82È\81I");
906         restfakecorr(grd);
907         return 0; /* didn't move */
908     }
909     x = grd->mx;
910     y = grd->my;
911
912     if (u_in_vault)
913         goto nextpos;
914
915     /* look around (hor & vert only) for accessible places */
916     for (nx = x - 1; nx <= x + 1; nx++)
917         for (ny = y - 1; ny <= y + 1; ny++) {
918             if ((nx == x || ny == y) && (nx != x || ny != y)
919                 && isok(nx, ny)) {
920                 typ = (crm = &levl[nx][ny])->typ;
921                 if (!IS_STWALL(typ) && !IS_POOL(typ)) {
922                     if (in_fcorridor(grd, nx, ny))
923                         goto nextnxy;
924
925                     if (*in_rooms(nx, ny, VAULT))
926                         continue;
927
928                     /* seems we found a good place to leave him alone */
929                     egrd->gddone = 1;
930                     if (ACCESSIBLE(typ))
931                         goto newpos;
932 #ifdef STUPID
933                     if (typ == SCORR)
934                         crm->typ = CORR;
935                     else
936                         crm->typ = DOOR;
937 #else
938                     crm->typ = (typ == SCORR) ? CORR : DOOR;
939 #endif
940                     if (crm->typ == DOOR)
941                         crm->doormask = D_NODOOR;
942                     goto proceed;
943                 }
944             }
945         nextnxy:
946             ;
947         }
948 nextpos:
949     nx = x;
950     ny = y;
951     gx = egrd->gdx;
952     gy = egrd->gdy;
953     dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
954     dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
955     if (abs(gx - x) >= abs(gy - y))
956         nx += dx;
957     else
958         ny += dy;
959
960     while ((typ = (crm = &levl[nx][ny])->typ) != STONE) {
961         /* in view of the above we must have IS_WALL(typ) or typ == POOL */
962         /* must be a wall here */
963         if (isok(nx + nx - x, ny + ny - y) && !IS_POOL(typ)
964             && IS_ROOM(levl[nx + nx - x][ny + ny - y].typ)) {
965             crm->typ = DOOR;
966             crm->doormask = D_NODOOR;
967             goto proceed;
968         }
969         if (dy && nx != x) {
970             nx = x;
971             ny = y + dy;
972             continue;
973         }
974         if (dx && ny != y) {
975             ny = y;
976             nx = x + dx;
977             dy = 0;
978             continue;
979         }
980         /* I don't like this, but ... */
981         if (IS_ROOM(typ)) {
982             crm->typ = DOOR;
983             crm->doormask = D_NODOOR;
984             goto proceed;
985         }
986         break;
987     }
988     crm->typ = CORR;
989 proceed:
990     newspot = TRUE;
991     unblock_point(nx, ny); /* doesn't block light */
992     if (cansee(nx, ny))
993         newsym(nx, ny);
994
995     fcp = &(egrd->fakecorr[egrd->fcend]);
996     if (egrd->fcend++ == FCSIZ)
997         panic("fakecorr overflow");
998     fcp->fx = nx;
999     fcp->fy = ny;
1000     fcp->ftyp = typ;
1001 newpos:
1002     if (egrd->gddone) {
1003         /* The following is a kludge.  We need to keep    */
1004         /* the guard around in order to be able to make   */
1005         /* the fake corridor disappear as the player      */
1006         /* moves out of it, but we also need the guard    */
1007         /* out of the way.  We send the guard to never-   */
1008         /* never land.  We set ogx ogy to mx my in order  */
1009         /* to avoid a check at the top of this function.  */
1010         /* At the end of the process, the guard is killed */
1011         /* in restfakecorr().                             */
1012     cleanup:
1013         x = grd->mx;
1014         y = grd->my;
1015
1016         see_guard = canspotmon(grd);
1017         wallify_vault(grd);
1018         remove_monster(grd->mx, grd->my);
1019         newsym(grd->mx, grd->my);
1020         place_monster(grd, 0, 0);
1021         egrd->ogx = grd->mx;
1022         egrd->ogy = grd->my;
1023         restfakecorr(grd);
1024         if (!semi_dead && (in_fcorridor(grd, u.ux, u.uy) || cansee(x, y))) {
1025             if (!disappear_msg_seen && see_guard)
1026 /*JP
1027                 pline("Suddenly, %s disappears.", noit_mon_nam(grd));
1028 */
1029                 pline("\93Ë\91R\81C%s\82Í\8fÁ\82¦\82½\81D", noit_mon_nam(grd));
1030             return 1;
1031         }
1032         return -2;
1033     }
1034     egrd->ogx = grd->mx; /* update old positions */
1035     egrd->ogy = grd->my;
1036     remove_monster(grd->mx, grd->my);
1037     place_monster(grd, nx, ny);
1038     if (newspot && g_at(nx, ny)) {
1039         /* if there's gold already here (most likely from mineralize()),
1040            pick it up now so that guard doesn't later think hero dropped
1041            it and give an inappropriate message */
1042         mpickgold(grd);
1043         if (canspotmon(grd))
1044 /*JP
1045             pline("%s picks up some gold.", Monnam(grd));
1046 */
1047             pline("%s\82Í\8bà\82ð\8fE\82Á\82½\81D", Monnam(grd));
1048     } else
1049         newsym(grd->mx, grd->my);
1050     restfakecorr(grd);
1051     return 1;
1052 }
1053
1054 /* Routine when dying or quitting with a vault guard around */
1055 void
1056 paygd()
1057 {
1058     register struct monst *grd = findgd();
1059     long umoney = money_cnt(invent);
1060     struct obj *coins, *nextcoins;
1061     int gx, gy;
1062     char buf[BUFSZ];
1063
1064     if (!umoney || !grd)
1065         return;
1066
1067     if (u.uinvault) {
1068 #if 0 /*JP*/
1069         Your("%ld %s goes into the Magic Memory Vault.", umoney,
1070              currency(umoney));
1071 #else
1072         Your("%ld%s\82Í\96\82\96@\82Ì\8bL\94O\91q\8cÉ\82É\93ü\82Á\82½\81D", umoney,
1073              currency(umoney));
1074 #endif
1075         gx = u.ux;
1076         gy = u.uy;
1077     } else {
1078         if (grd->mpeaceful) { /* guard has no "right" to your gold */
1079             mongone(grd);
1080             return;
1081         }
1082         mnexto(grd);
1083 /*JP
1084         pline("%s remits your gold to the vault.", Monnam(grd));
1085 */
1086         pline("%s\82Í\82 \82È\82½\82Ì\8bà\89Ý\82ð\91q\8cÉ\82É\91\97\82Á\82½\81D", Monnam(grd));
1087         gx = rooms[EGD(grd)->vroom].lx + rn2(2);
1088         gy = rooms[EGD(grd)->vroom].ly + rn2(2);
1089 #if 0 /*JP*/
1090         Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.",
1091                 plname, mons[u.umonster].mname);
1092 #else
1093         Sprintf(buf, "\83N\83\8d\83C\83\\83X\82Ö: \82±\82±\82É%s\82Ì%s\82©\82ç\8eæ\82è\96ß\82µ\82½\8bà\89Ý\82ð\91\97\82é\81D",
1094                 mons[u.umonster].mname, plname);
1095 #endif
1096         make_grave(gx, gy, buf);
1097     }
1098     for (coins = invent; coins; coins = nextcoins) {
1099         nextcoins = coins->nobj;
1100         if (objects[coins->otyp].oc_class == COIN_CLASS) {
1101             freeinv(coins);
1102             place_object(coins, gx, gy);
1103             stackobj(coins);
1104         }
1105     }
1106     mongone(grd);
1107 }
1108
1109 long
1110 hidden_gold()
1111 {
1112     long value = 0L;
1113     struct obj *obj;
1114
1115     for (obj = invent; obj; obj = obj->nobj)
1116         if (Has_contents(obj))
1117             value += contained_gold(obj);
1118     /* unknown gold stuck inside statues may cause some consternation... */
1119
1120     return value;
1121 }
1122
1123 /* prevent "You hear footsteps.." when inappropriate */
1124 boolean
1125 gd_sound()
1126 {
1127     struct monst *grd = findgd();
1128
1129     if (vault_occupied(u.urooms))
1130         return FALSE;
1131     else
1132         return (boolean) (grd == (struct monst *) 0);
1133 }
1134
1135 void
1136 vault_gd_watching(activity)
1137 unsigned int activity;
1138 {
1139     struct monst *guard = findgd();
1140
1141     if (guard && guard->mcansee && m_canseeu(guard)) {
1142         if (activity == GD_EATGOLD || activity == GD_DESTROYGOLD)
1143             EGD(guard)->witness = activity;
1144     }
1145 }
1146
1147 /*vault.c*/