1 /* NetHack 3.6 vault.c $NHDT-Date: 1549921171 2019/02/11 21:39:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.62 $ */
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. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *, BOOLEAN_P));
14 STATIC_DCL void FDECL(blackout, (int, int));
15 STATIC_DCL void FDECL(restfakecorr, (struct monst *));
16 STATIC_DCL void FDECL(parkguard, (struct monst *));
17 STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *, int, int));
18 STATIC_DCL boolean FDECL(find_guard_dest, (struct monst *, xchar *, xchar *));
19 STATIC_DCL void FDECL(move_gold, (struct obj *, int));
20 STATIC_DCL void FDECL(wallify_vault, (struct monst *));
21 STATIC_DCL void FDECL(gd_mv_monaway, (struct monst *, int, int));
22 STATIC_OVL void FDECL(gd_pick_corridor_gold, (struct monst *, int, int));
29 mtmp->mextra = newmextra();
31 EGD(mtmp) = (struct egd *) alloc(sizeof (struct egd));
32 (void) memset((genericptr_t) EGD(mtmp), 0, sizeof (struct egd));
40 if (mtmp->mextra && EGD(mtmp)) {
41 free((genericptr_t) EGD(mtmp));
42 EGD(mtmp) = (struct egd *) 0;
47 /* try to remove the temporary corridor (from vault to rest of map) being
48 maintained by guard 'grd'; if guard is still in it, removal will fail,
49 to be tried again later */
51 clear_fcorr(grd, forceshow)
55 register int fcx, fcy, fcbeg;
57 boolean sawcorridor = FALSE,
58 silently = program_state.stopprint ? TRUE : FALSE;
59 struct egd *egrd = EGD(grd);
63 if (!on_level(&egrd->gdlevel, &u.uz))
66 /* note: guard remains on 'fmons' list (alive or dead, at off-map
67 coordinate <0,0>), until temporary corridor from vault back to
68 civilization has been removed */
69 while ((fcbeg = egrd->fcbeg) < egrd->fcend) {
70 fcx = egrd->fakecorr[fcbeg].fx;
71 fcy = egrd->fakecorr[fcbeg].fy;
72 if ((DEADMONSTER(grd) || !in_fcorridor(grd, u.ux, u.uy))
75 if ((u.ux == fcx && u.uy == fcy && !DEADMONSTER(grd))
76 || (!forceshow && couldsee(fcx, fcy))
77 || (Punished && !carried(uball) && uball->ox == fcx
81 if ((mtmp = m_at(fcx, fcy)) != 0) {
84 } else if (!in_fcorridor(grd, u.ux, u.uy)) {
87 (void) rloc(mtmp, FALSE);
90 lev = &levl[fcx][fcy];
91 if (lev->typ == CORR && cansee(fcx, fcy))
93 lev->typ = egrd->fakecorr[fcbeg].ftyp;
94 if (IS_STWALL(lev->typ)) {
95 /* destroy any trap here (pit dug by you, hole dug via
96 wand while levitating or by monster, bear trap or land
97 mine via object, spun web) when spot reverts to stone */
98 if ((trap = t_at(fcx, fcy)) != 0)
100 /* undo scroll/wand/spell of light affecting this spot */
101 if (lev->typ == STONE)
104 map_location(fcx, fcy, 1); /* bypass vision */
105 if (!ACCESSIBLE(lev->typ))
106 block_point(fcx, fcy);
107 vision_full_recalc = 1;
110 if (sawcorridor && !silently)
112 pline_The("corridor disappears.");
114 pline("
\92Ê
\98H
\82Í
\8fÁ
\82¦
\82½
\81D");
115 /* only give encased message if hero is still alive (might get here
116 via paygd() -> mongone() -> grddead() when game is over;
117 died: no message, quit: message) */
118 if (IS_ROCK(levl[u.ux][u.uy].typ) && (Upolyd ? u.mh : u.uhp) > 0
121 You("are encased in rock.");
123 You("
\90Î
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81D");
127 /* as a temporary corridor is removed, set stone locations and adjacent
128 spots to unlit; if player used scroll/wand/spell of light while inside
129 the corridor, we don't want the light to reappear if/when a new tunnel
130 goes through the same area */
138 for (i = x - 1; i <= x + 1; ++i)
139 for (j = y - 1; j <= y + 1; ++j) {
143 /* [possible bug: when (i != x || j != y), perhaps we ought
144 to check whether the spot on the far side is lit instead
145 of doing a blanket blackout of adjacent locations] */
146 if (lev->typ == STONE)
147 lev->lit = lev->waslit = 0;
148 /* mark <i,j> as not having been seen from <x,y> */
149 unset_seenv(lev, x, y, i, j);
157 /* it seems you left the corridor - let the guard disappear */
158 if (clear_fcorr(grd, FALSE)) {
159 grd->isgd = 0; /* dmonsfree() should delete this mon */
164 /* move guard--dead to alive--to <0,0> until temporary corridor is removed */
169 /* either guard is dead or will now be treated as if so;
170 monster traversal loops should skip it */
171 if (grd == context.polearm.hitmon)
172 context.polearm.hitmon = 0;
174 remove_monster(grd->mx, grd->my);
175 newsym(grd->mx, grd->my);
176 place_monster(grd, 0, 0);
177 /* [grd->mx,my just got set to 0,0 by place_monster(), so this
178 just sets EGD(grd)->ogx,ogy to 0,0 too; is that what we want?] */
179 EGD(grd)->ogx = grd->mx;
180 EGD(grd)->ogy = grd->my;
184 /* called in mon.c */
189 boolean dispose = clear_fcorr(grd, TRUE);
192 /* destroy guard's gold; drop any other inventory */
193 relobj(grd, 0, FALSE);
196 dispose = clear_fcorr(grd, TRUE);
199 grd->isgd = 0; /* for dmonsfree() */
204 in_fcorridor(grd, x, y)
209 struct egd *egrd = EGD(grd);
211 for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
212 if (x == egrd->fakecorr[fci].fx && y == egrd->fakecorr[fci].fy)
220 register struct monst *mtmp;
222 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
223 if (DEADMONSTER(mtmp))
225 if (mtmp->isgd && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
228 return (struct monst *) 0;
234 if (vault_occupied(u.urooms) && !findgd())
235 u.uinvault = (VAULT_GUARD_TIME - 1);
239 vault_occupied(array)
244 for (ptr = array; *ptr; ptr++)
245 if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
250 /* hero has teleported out of vault while a guard is active */
255 /* only called if caller has checked vault_occupied() and findgd() */
256 if (!grd || !grd->isgd || DEADMONSTER(grd)) {
257 impossible("escaping vault without guard?");
260 /* if carrying gold and arriving anywhere other than next to the guard,
261 set the guard loose */
262 if ((money_cnt(invent) || hidden_gold())
263 && um_dist(grd->mx, grd->my, 1)) {
264 if (grd->mpeaceful) {
265 if (canspotmon(grd)) /* see or sense via telepathy */
267 pline("%s becomes irate.", Monnam(grd));
269 pline("%s
\82Í
\8c\83\93{
\82µ
\82½
\81D", Monnam(grd));
270 grd->mpeaceful = 0; /* bypass setmangry() */
272 /* if arriving outside guard's temporary corridor, give the
273 guard an extra move to deliver message(s) and to teleport
274 out of and remove that corridor */
275 if (!in_fcorridor(grd, u.ux, u.uy))
281 find_guard_dest(guard, rx, ry)
285 register int x, y, dd, lx = 0, ly = 0;
287 for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
288 for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) {
289 if (y < 0 || y > ROWNO - 1)
291 for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) {
292 if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
294 if (x < 1 || x > COLNO - 1)
296 if (guard && ((x == guard->mx && y == guard->my)
297 || (guard->isgd && in_fcorridor(guard, x, y))))
299 if (levl[x][y].typ == CORR) {
300 lx = (x < u.ux) ? x + 1 : (x > u.ux) ? x - 1 : x;
301 ly = (y < u.uy) ? y + 1 : (y > u.uy) ? y - 1 : y;
302 if (levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
313 impossible("Not a single corridor on this level?");
322 int dummy; /* hack to avoid schain botch */
326 int trycount, vaultroom = (int) vault_occupied(u.urooms);
332 vaultroom -= ROOMOFFSET;
335 if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) {
336 /* if time ok and no guard now. */
338 register int x, y, gx, gy;
342 /* first find the goal for the guard */
343 if (!find_guard_dest((struct monst *)0, &rx, &ry))
347 /* next find a good place for a door in the wall */
350 if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */
351 if (levl[x + 1][y].typ == ROOM)
353 else if (levl[x][y + 1].typ == ROOM)
355 else if (levl[x - 1][y].typ == ROOM)
357 else if (levl[x][y - 1].typ == ROOM)
359 else if (levl[x + 1][y + 1].typ == ROOM) {
362 } else if (levl[x - 1][y - 1].typ == ROOM) {
365 } else if (levl[x + 1][y - 1].typ == ROOM) {
368 } else if (levl[x - 1][y + 1].typ == ROOM) {
373 while (levl[x][y].typ == ROOM) {
376 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
377 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
378 if (abs(gx - x) >= abs(gy - y))
383 if (x == u.ux && y == u.uy) {
384 if (levl[x + 1][y].typ == HWALL || levl[x + 1][y].typ == DOOR)
386 else if (levl[x - 1][y].typ == HWALL
387 || levl[x - 1][y].typ == DOOR)
389 else if (levl[x][y + 1].typ == VWALL
390 || levl[x][y + 1].typ == DOOR)
392 else if (levl[x][y - 1].typ == VWALL
393 || levl[x][y - 1].typ == DOOR)
399 /* make something interesting happen */
400 if (!(guard = makemon(&mons[PM_GUARD], x, y, MM_EGD)))
403 guard->mpeaceful = 1;
405 EGD(guard)->gddone = 0;
408 assign_level(&(EGD(guard)->gdlevel), &u.uz);
409 EGD(guard)->vroom = vaultroom;
410 EGD(guard)->warncnt = 0;
412 reset_faint(); /* if fainted - wake up */
413 gsensed = !canspotmon(guard);
416 pline("Suddenly one of the Vault's %s enters!",
417 makeplural(guard->data->mname));
419 pline("
\93Ë
\91R
\81C
\91q
\8cÉ
\82Ì
\94Ô
\95º
\82ª
\93ü
\82Á
\82Ä
\82«
\82½
\81I");
423 pline("Someone else has entered the Vault.");
425 pline("
\92N
\82©
\82ª
\91q
\8cÉ
\82É
\93ü
\82Á
\82Ä
\82«
\82½
\81D");
426 newsym(guard->mx, guard->my);
428 /* can't interrogate hero, don't interrogate engulfer */
431 verbalize("What's going on here?");
433 verbalize("
\82±
\82±
\82Å
\89½
\82ð
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\81H");
436 pline_The("other presence vanishes.");
438 pline("
\91¼
\90l
\82Ì
\8bC
\94z
\82Í
\8fÁ
\82¦
\82½
\81D");
442 if (U_AP_TYPE == M_AP_OBJECT || u.uundetected) {
443 if (U_AP_TYPE == M_AP_OBJECT
444 && youmonst.mappearance != GOLD_PIECE)
447 verbalize("Hey! Who left that %s in here?",
448 mimic_obj_name(&youmonst));
450 verbalize("
\82¨
\82¢
\81I
\82¾
\82ê
\82ª
\82±
\82Ì%s
\82ð
\82±
\82±
\82É
\92u
\82¢
\82Ä
\8ds
\82Á
\82½
\82ñ
\82¾
\81H",
451 mimic_obj_name(&youmonst));
453 /* You're mimicking some object or you're hidden. */
455 pline("Puzzled, %s turns around and leaves.", mhe(guard));
457 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));
461 if (Strangled || is_silent(youmonst.data) || multi < 0) {
462 /* [we ought to record whether this this message has already
463 been given in order to vary it upon repeat visits, but
464 discarding the monster and its egd data renders that hard] */
467 pline("%s huffs and turns to leave.", noit_Monnam(guard));
469 pline("%s
\82Í
\95s
\8b@
\8c\99\82É
\82È
\82Á
\82Ä
\81C
\8b\8e\82Á
\82Ä
\82¢
\82Á
\82½
\81D", noit_Monnam(guard));
472 verbalize("I'll be back when you're ready to speak to me!");
474 verbalize("
\98b
\82¹
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82ç
\96ß
\82Á
\82Ä
\82«
\82Ä
\82â
\82é
\81I");
479 stop_occupation(); /* if occupied, stop it *now* */
488 getlin(Deaf ? "You are required to supply your name. -"
489 : "\"Hello stranger, who are you?\" -", buf);
491 getlin(Deaf ? "
\96¼
\91O
\82ð
\8c¾
\82¤
\82æ
\82¤
\82É
\8b\81\82ß
\82ç
\82ê
\82½
\81D-"
492 : "
\81u
\8c©
\82È
\82¢
\8aç
\82¾
\82È
\81C
\82¨
\82Ü
\82¦
\82Í
\92N
\82¾
\81H
\81v-", buf);
494 (void) mungspaces(buf);
496 } while (!buf[0] && --trycount > 0);
498 } while (!buf[0] && !is_kanji(buf[0]) && --trycount > 0);
501 if (u.ualign.type == A_LAWFUL
502 /* ignore trailing text, in case player includes rank */
503 && strncmpi(buf, plname, (int) strlen(plname)) != 0) {
504 adjalign(-1); /* Liar! */
508 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
509 || !strcmpi(buf, "Creosote")) { /* Discworld */
511 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
512 || !strcmpi(buf, "Creosote") /* Discworld */
513 || !strcmp(buf, "
\83N
\83\8d\83C
\83\
\83X") || !strcmp(buf, "
\83N
\83\8c\83I
\83\
\81[
\83g")) {
515 if (!mvitals[PM_CROESUS].died) {
519 pline("%s waves goodbye.", noit_Monnam(guard));
521 pline("%s
\82Í
\82³
\82æ
\82È
\82ç
\82Æ
\8eè
\82ð
\90U
\82Á
\82½
\81D", noit_Monnam(guard));
525 "Oh, yes, of course. Sorry to have disturbed you.");
527 "
\82¢
\82â
\81C
\82±
\82è
\82á
\81C
\82¦
\81[
\82Æ
\81C
\82¨
\91\9b\82ª
\82¹
\82µ
\82Ü
\82µ
\82½
\81D");
531 setmangry(guard, FALSE);
535 pline("%s mouths something and looks very angry!",
538 pline("%s
\82Í
\89½
\82©
\82ð
\8c¾
\82Á
\82Ä
\82¢
\82é
\81D
\82Æ
\82Ä
\82à
\93{
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81I",
544 "Back from the dead, are you? I'll remedy that!");
547 "
\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");
550 /* don't want guard to waste next turn wielding a weapon */
551 if (!MON_WEP(guard)) {
552 guard->weapon_check = NEED_HTH_WEAPON;
553 (void) mon_wield_item(guard);
560 pline("%s doesn't %srecognize you.", noit_Monnam(guard),
561 (Blind) ? "" : "appear to ");
563 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82±
\82Æ
\82ª
\95ª
\82©
\82ç
\82È
\82¢
\82æ
\82¤
\82¾
\81D", noit_Monnam(guard));
567 verbalize("I don't know you.");
569 verbalize("
\92m
\82ç
\82ñ
\82È
\81D");
570 umoney = money_cnt(invent);
571 if (!umoney && !hidden_gold()) {
574 pline("%s stomps%s.", noit_Monnam(guard),
575 (Blind) ? "" : " and beckons");
577 pline("%s
\82Í
\91«
\82ð
\93¥
\82Ý
\96Â
\82ç
\82µ%s
\82½
\81D", noit_Monnam(guard),
578 (Blind) ? "" : "
\82Ä
\8eè
\8fµ
\82«
\82µ");
582 verbalize("Please follow me.");
584 verbalize("
\8e\84\82Ì
\8cã
\82É
\82Â
\82¢
\82Ä
\82«
\82È
\82³
\82¢
\81D");
590 pline("%s glares at you%s.", noit_Monnam(guard),
591 invent ? "r stuff" : "");
593 pline("%s
\82Í
\82 \82È
\82½%s
\82ð
\82É
\82ç
\82Ý
\82Â
\82¯
\82½
\81D", noit_Monnam(guard),
594 invent ? "
\82Ì
\8e\9d\82¿
\95¨" : "");
598 verbalize("You have hidden gold.");
600 verbalize("
\82Ü
\82¾
\8bà
\89Ý
\82ð
\89B
\82µ
\82Ä
\82é
\82È
\81D");
607 "%s holds out %s palm and beckons with %s other hand.",
608 noit_Monnam(guard), noit_mhis(guard),
612 "%s
\82Í
\95Ð
\8eè
\82ð
\8d·
\82µ
\8fo
\82µ
\81C
\82à
\82¤
\95Ð
\8eè
\82Å
\8eè
\8fµ
\82«
\82µ
\82½
\81D",
618 "Most likely all your gold was stolen from this vault.");
620 "
\91q
\8cÉ
\82©
\82ç
\93\90\82ñ
\82¾
\8bà
\89Ý
\82ª
\82 \82é
\82¾
\82ë
\82¤
\81D");
622 verbalize("Please drop that gold and follow me.");
624 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");
627 EGD(guard)->gdx = gx;
628 EGD(guard)->gdy = gy;
629 EGD(guard)->fcbeg = 0;
630 EGD(guard)->fakecorr[0].fx = x;
631 EGD(guard)->fakecorr[0].fy = y;
632 if (IS_WALL(levl[x][y].typ)) {
633 EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
634 } else { /* the initial guard location is a dug door */
635 int vlt = EGD(guard)->vroom;
636 xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
637 xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
639 if (x == lowx - 1 && y == lowy - 1)
640 EGD(guard)->fakecorr[0].ftyp = TLCORNER;
641 else if (x == hix + 1 && y == lowy - 1)
642 EGD(guard)->fakecorr[0].ftyp = TRCORNER;
643 else if (x == lowx - 1 && y == hiy + 1)
644 EGD(guard)->fakecorr[0].ftyp = BLCORNER;
645 else if (x == hix + 1 && y == hiy + 1)
646 EGD(guard)->fakecorr[0].ftyp = BRCORNER;
647 else if (y == lowy - 1 || y == hiy + 1)
648 EGD(guard)->fakecorr[0].ftyp = HWALL;
649 else if (x == lowx - 1 || x == hix + 1)
650 EGD(guard)->fakecorr[0].ftyp = VWALL;
652 levl[x][y].typ = DOOR;
653 levl[x][y].doormask = D_NODOOR;
654 unblock_point(x, y); /* doesn't block light */
655 EGD(guard)->fcend = 1;
656 EGD(guard)->warncnt = 1;
661 move_gold(gold, vroom)
668 newsym(gold->ox, gold->oy);
669 nx = rooms[vroom].lx + rn2(2);
670 ny = rooms[vroom].ly + rn2(2);
671 place_object(gold, nx, ny);
681 int vlt = EGD(grd)->vroom;
683 xchar lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1,
684 loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1;
688 boolean fixed = FALSE;
689 boolean movedgold = FALSE;
691 for (x = lox; x <= hix; x++)
692 for (y = loy; y <= hiy; y++) {
693 /* if not on the room boundary, skip ahead */
694 if (x != lox && x != hix && y != loy && y != hiy)
697 if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
698 if ((mon = m_at(x, y)) != 0 && mon != grd) {
701 (void) rloc(mon, FALSE);
703 if ((gold = g_at(x, y)) != 0) {
704 move_gold(gold, EGD(grd)->vroom);
707 if ((trap = t_at(x, y)) != 0)
711 (y == loy) ? TLCORNER : (y == hiy) ? BLCORNER : VWALL;
714 (y == loy) ? TRCORNER : (y == hiy) ? BRCORNER : VWALL;
715 else /* not left or right side, must be top or bottom */
717 levl[x][y].typ = typ;
718 levl[x][y].doormask = 0;
720 * hack: player knows walls are restored because of the
721 * message, below, so show this on the screen.
723 tmp_viz = viz_array[y][x];
724 viz_array[y][x] = IN_SIGHT | COULD_SEE;
726 viz_array[y][x] = tmp_viz;
732 if (movedgold || fixed) {
733 if (in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
735 pline("%s whispers an incantation.", noit_Monnam(grd));
737 pline("%s
\82Í
\8eô
\95¶
\82ð
\82³
\82³
\82â
\82¢
\82½
\81D", noit_Monnam(grd));
740 You_hear("a distant chant.");
742 You_hear("
\89\93\95û
\82Å
\82Ì
\8eô
\95¶
\82ð
\95·
\82¢
\82½
\81D");
745 pline("A mysterious force moves the gold into the vault.");
747 pline("
\95s
\8ev
\8bc
\82È
\97Í
\82ª
\8bà
\89Ý
\82ð
\91q
\8cÉ
\82Ö
\89^
\82ñ
\82¾
\81D");
750 pline_The("damaged vault's walls are magically restored!");
752 pline("
\8f\9d\82Â
\82¢
\82½
\91q
\8cÉ
\82Ì
\95Ç
\82Í
\96\82\96@
\82Å
\95\9c\8c³
\82³
\82ê
\82½
\81I");
757 gd_mv_monaway(grd, nx, ny)
758 register struct monst *grd;
761 if (MON_AT(nx, ny) && !(nx == grd->mx && ny == grd->my)) {
764 verbalize("Out of my way, scum!");
766 verbalize("
\96Ú
\82Ì
\91O
\82©
\82ç
\8fÁ
\82¦
\82ë
\81C
\83N
\83\
\82Á
\82½
\82ê
\81I");
767 if (!rloc(m_at(nx, ny), FALSE) || MON_AT(nx, ny))
768 m_into_limbo(m_at(nx, ny));
772 /* have guard pick gold off the floor, possibly moving to the gold's
773 position before message and back to his current spot after */
775 gd_pick_corridor_gold(grd, goldx, goldy)
777 int goldx, goldy; /* <gold->ox, gold->oy> */
781 int gdelta, newdelta, bestdelta, tryct,
782 guardx = grd->mx, guardy = grd->my;
783 boolean under_u = (goldx == u.ux && goldy == u.uy),
784 see_it = cansee(goldx, goldy);
787 /* Grab the gold from between the hero's feet.
788 If guard is two or more steps away; bring him closer first. */
789 gold = g_at(goldx, goldy);
791 impossible("vault guard: no gold at hero's feet?");
794 gdelta = distu(guardx, guardy);
795 if (gdelta > 2 && see_it) { /* skip if player won't see it */
797 bestcc.x = (xchar) guardx, bestcc.y = (xchar) guardy;
800 /* pick an available spot nearest the hero and also try
801 to find the one meeting that criterium which is nearest
802 the guard's current location */
803 if (enexto(&newcc, goldx, goldy, grd->data)) {
804 if ((newdelta = distu(newcc.x, newcc.y)) < bestdelta
805 || (newdelta == bestdelta
806 && dist2(newcc.x, newcc.y, guardx, guardy)
807 < dist2(bestcc.x, bestcc.y, guardx, guardy))) {
808 bestdelta = newdelta;
812 } while (--tryct >= 0);
814 if (bestdelta < gdelta) {
815 remove_monster(guardx, guardy);
816 newsym(guardx, guardy);
817 place_monster(grd, (int) bestcc.x, (int) bestcc.y);
818 newsym(grd->mx, grd->my);
821 obj_extract_self(gold);
822 add_to_minv(grd, gold);
823 newsym(goldx, goldy);
825 /* guard is already at gold's location */
826 } else if (goldx == guardx && goldy == guardy) {
827 mpickgold(grd); /* does a newsym */
829 /* gold is at some third spot, neither guard's nor hero's */
831 /* just for insurance... */
832 gd_mv_monaway(grd, goldx, goldy); /* make room for guard */
833 if (see_it) { /* skip if player won't see the message */
834 remove_monster(grd->mx, grd->my);
835 newsym(grd->mx, grd->my);
836 place_monster(grd, goldx, goldy); /* sets <grd->mx, grd->my> */
838 mpickgold(grd); /* does a newsym */
841 if (see_it) { /* cansee(goldx, goldy) */
842 char monnambuf[BUFSZ];
844 Strcpy(monnambuf, Monnam(grd));
845 if (!strcmpi(monnambuf, "It"))
846 Strcpy(monnambuf, "Someone");
848 pline("%s%s picks up the gold%s.", monnambuf,
849 (grd->mpeaceful && EGD(grd)->warncnt > 5)
850 ? " calms down and" : "",
851 under_u ? " from beneath you" : "");
853 pline("%s
\82Í%s%s
\8bà
\89Ý
\82ð
\8fE
\82Á
\82½
\81D", monnambuf,
854 (grd->mpeaceful && EGD(grd)->warncnt > 5)
855 ? "
\93{
\82è
\82ð
\90Ã
\82ß" : "",
856 under_u ? "
\82 \82È
\82½
\82Ì
\91«
\8c³
\82Ì" : "");
860 /* if guard was moved to get the gold, move him back */
861 if (grd->mx != guardx || grd->my != guardy) {
862 remove_monster(grd->mx, grd->my);
863 newsym(grd->mx, grd->my);
864 place_monster(grd, guardx, guardy);
865 newsym(guardx, guardy);
871 * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died
875 register struct monst *grd;
877 int x, y, nx, ny, m, n;
878 int dx, dy, gx = 0, gy = 0, fci;
881 struct fakecorridor *fcp;
882 register struct egd *egrd = EGD(grd);
884 boolean goldincorridor = FALSE, u_in_vault = FALSE, grd_in_vault = FALSE,
885 disappear_msg_seen = FALSE, semi_dead = DEADMONSTER(grd),
886 u_carry_gold = FALSE, newspot = FALSE, see_guard;
888 if (!on_level(&(egrd->gdlevel), &u.uz))
891 if (semi_dead || !grd->mx || egrd->gddone) {
895 debugpline1("gd_move: %s guard", grd->mpeaceful ? "peaceful" : "hostile");
897 u_in_vault = vault_occupied(u.urooms) ? TRUE : FALSE;
898 grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? TRUE : FALSE;
899 if (!u_in_vault && !grd_in_vault)
902 if (!grd->mpeaceful) {
904 && (grd_in_vault || (in_fcorridor(grd, grd->mx, grd->my)
905 && !in_fcorridor(grd, u.ux, u.uy)))) {
906 (void) rloc(grd, FALSE);
908 (void) clear_fcorr(grd, TRUE);
911 if (!in_fcorridor(grd, grd->mx, grd->my))
912 (void) clear_fcorr(grd, TRUE);
915 if (abs(egrd->ogx - grd->mx) > 1 || abs(egrd->ogy - grd->my) > 1)
916 return -1; /* teleported guard - treat as monster */
921 verbalize("How dare you %s that gold, scoundrel!",
922 (egrd->witness & GD_EATGOLD) ? "consume" : "destroy");
924 verbalize("
\82æ
\82
\82à
\82Ü
\82 \8bà
\82ð%s
\82à
\82Ì
\82¾
\81C
\88«
\93}
\82ß
\81I",
925 (egrd->witness & GD_EATGOLD) ? "
\8eg
\82Á
\82½" : "
\89ó
\82µ
\82½");
932 umoney = money_cnt(invent);
933 u_carry_gold = umoney > 0L || hidden_gold() > 0L;
934 if (egrd->fcend == 1) {
935 if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
936 if (egrd->warncnt == 3 && !Deaf)
938 verbalize("I repeat, %sfollow me!",
940 ? (!umoney ? "drop that hidden money and "
941 : "drop that money and ")
944 verbalize("
\8cJ
\82è
\95Ô
\82·
\81I%s
\8e\84\82É
\82Â
\82¢
\82Ä
\82±
\82¢
\81I",
946 ? (!umoney ? "
\89B
\82µ
\8e\9d\82Á
\82Ä
\82é
\8bà
\82ð
\92u
\82¢
\82Ä"
947 : "
\8bà
\82ð
\92u
\82¢
\82Ä")
950 if (egrd->warncnt == 7) {
955 verbalize("You've been warned, knave!");
957 verbalize("
\8cx
\8d\90\82Í
\82µ
\82½
\82¼
\81C
\88«
\93}
\82ß
\81I");
959 levl[m][n].typ = egrd->fakecorr[0].ftyp;
964 /* not fair to get mad when (s)he's fainted or paralyzed */
965 if (!is_fainted() && multi >= 0)
971 if (u_carry_gold) { /* player teleported */
974 (void) rloc(grd, TRUE);
975 levl[m][n].typ = egrd->fakecorr[0].ftyp;
979 if (!cansee(grd->mx, grd->my) || !mon_visible(grd))
982 m_carrying(grd, TIN_WHISTLE)
983 ? "the shrill sound of a guard's whistle"
986 You_hear("%s
\82ð
\95·
\82¢
\82½
\81D",
987 m_carrying(grd, TIN_WHISTLE)
988 ? "
\94Ô
\95º
\82Ì
\89s
\82¢
\93J
\82Ì
\89¹"
989 : "
\93{
\82è
\82Ì
\8b©
\82Ñ");
993 You(um_dist(grd->mx, grd->my, 2)
994 ? "see %s approaching."
995 : "are confronted by %s.",
996 /* "an angry guard" */
997 x_monnam(grd, ARTICLE_A, "angry", 0, FALSE));
999 You(um_dist(grd->mx, grd->my, 2)
1000 ? "%s
\82ª
\8bß
\82Ã
\82¢
\82Ä
\82
\82é
\82Ì
\82ð
\8c©
\82½
\81D"
1001 : "%s
\82Æ
\91Î
\9b³
\82µ
\82½
\81D",
1002 x_monnam(grd, ARTICLE_A, "
\93{
\82Á
\82½", 0, FALSE));
1008 verbalize("Well, begone.");
1010 verbalize("
\97§
\82¿
\8b\8e\82ê
\81D");
1017 if (egrd->fcend > 1) {
1018 if (egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my)
1019 && !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy)
1020 && levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
1021 == egrd->fakecorr[0].ftyp) {
1023 pline("%s, confused, disappears.", noit_Monnam(grd));
1025 pline("%s
\82Í
\8d¬
\97\90\82µ
\81C
\8fÁ
\82¦
\82½
\81D", noit_Monnam(grd));
1026 disappear_msg_seen = TRUE;
1029 if (u_carry_gold && (in_fcorridor(grd, u.ux, u.uy)
1030 /* cover a 'blind' spot */
1031 || (egrd->fcend > 1 && u_in_vault))) {
1036 if (egrd->warncnt < 6) {
1041 pline("%s holds out %s palm demandingly!",
1042 noit_Monnam(grd), noit_mhis(grd));
1044 pline("%s
\82Í
\8cµ
\82µ
\82¢
\92²
\8eq
\82Å
\8eè
\82Ì
\82Ð
\82ç
\82ð
\8d·
\82µ
\8fo
\82µ
\82½
\81I",
1049 verbalize("Drop all your gold, scoundrel!");
1051 verbalize("
\8bà
\82ð
\91S
\95\94\92u
\82¢
\82Ä
\82ä
\82¯
\81C
\82È
\82ç
\82¸
\82à
\82Ì
\81I");
1058 pline("%s rubs %s hands with enraged delight!",
1059 noit_Monnam(grd), noit_mhis(grd));
1061 pline("%s
\82Í
\93{
\82è
\82È
\82ª
\82ç
\8eè
\82ð
\82·
\82è
\82 \82í
\82¹
\82½
\81I",
1066 verbalize("So be it, rogue!");
1068 verbalize("
\93\90\90l
\82ß
\81I");
1075 for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
1076 if (g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) {
1077 m = egrd->fakecorr[fci].fx;
1078 n = egrd->fakecorr[fci].fy;
1079 goldincorridor = TRUE;
1082 /* new gold can appear if it was embedded in stone and hero kicks it
1083 (on even via wish and drop) so don't assume hero has been warned */
1084 if (goldincorridor && !egrd->gddone) {
1085 gd_pick_corridor_gold(grd, m, n);
1086 if (!grd->mpeaceful)
1091 if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
1092 if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow
1093 && !(u.ustuck && !sticks(youmonst.data)))
1095 verbalize("Move along!");
1097 verbalize("
\97£
\82ê
\82é
\82È
\81I");
1099 return 0; /* didn't move */
1107 /* look around (hor & vert only) for accessible places */
1108 for (nx = x - 1; nx <= x + 1; nx++)
1109 for (ny = y - 1; ny <= y + 1; ny++) {
1110 if ((nx == x || ny == y) && (nx != x || ny != y)
1112 typ = (crm = &levl[nx][ny])->typ;
1113 if (!IS_STWALL(typ) && !IS_POOL(typ)) {
1114 if (in_fcorridor(grd, nx, ny))
1117 if (*in_rooms(nx, ny, VAULT))
1120 /* seems we found a good place to leave him alone */
1122 if (ACCESSIBLE(typ))
1130 crm->typ = (typ == SCORR) ? CORR : DOOR;
1132 if (crm->typ == DOOR)
1133 crm->doormask = D_NODOOR;
1145 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
1146 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
1147 if (abs(gx - x) >= abs(gy - y))
1152 while ((typ = (crm = &levl[nx][ny])->typ) != STONE) {
1153 /* in view of the above we must have IS_WALL(typ) or typ == POOL */
1154 /* must be a wall here */
1155 if (isok(nx + nx - x, ny + ny - y) && !IS_POOL(typ)
1156 && IS_ROOM(levl[nx + nx - x][ny + ny - y].typ)) {
1158 crm->doormask = D_NODOOR;
1161 if (dy && nx != x) {
1166 if (dx && ny != y) {
1172 /* I don't like this, but ... */
1175 crm->doormask = D_NODOOR;
1183 unblock_point(nx, ny); /* doesn't block light */
1187 if ((nx != gx || ny != gy) || (grd->mx != gx || grd->my != gy)) {
1188 fcp = &(egrd->fakecorr[egrd->fcend]);
1189 if (egrd->fcend++ == FCSIZ)
1190 panic("fakecorr overflow");
1194 } else if (!egrd->gddone) {
1195 /* We're stuck, so try to find a new destination. */
1196 if (!find_guard_dest(grd, &egrd->gdx, &egrd->gdy)
1197 || (egrd->gdx == gx && egrd->gdy == gy)) {
1199 pline("%s, confused, disappears.", Monnam(grd));
1201 pline("%s
\82Í
\8d¬
\97\90\82µ
\81C
\8fÁ
\82¦
\82½
\81D", Monnam(grd));
1202 disappear_msg_seen = TRUE;
1208 gd_mv_monaway(grd, nx, ny);
1210 /* The following is a kludge. We need to keep */
1211 /* the guard around in order to be able to make */
1212 /* the fake corridor disappear as the player */
1213 /* moves out of it, but we also need the guard */
1214 /* out of the way. We send the guard to never- */
1215 /* never land. We set ogx ogy to mx my in order */
1216 /* to avoid a check at the top of this function. */
1217 /* At the end of the process, the guard is killed */
1218 /* in restfakecorr(). */
1220 x = grd->mx, y = grd->my;
1221 see_guard = canspotmon(grd);
1222 parkguard(grd); /* move to <0,0> */
1225 debugpline2("gd_move: %scleanup%s",
1226 grd->isgd ? "" : "final ",
1227 grd->isgd ? " attempt" : "");
1228 if (!semi_dead && (in_fcorridor(grd, u.ux, u.uy) || cansee(x, y))) {
1229 if (!disappear_msg_seen && see_guard)
1231 pline("Suddenly, %s disappears.", noit_mon_nam(grd));
1233 pline("
\93Ë
\91R
\81C%s
\82Í
\8fÁ
\82¦
\82½
\81D", noit_mon_nam(grd));
1238 egrd->ogx = grd->mx; /* update old positions */
1239 egrd->ogy = grd->my;
1240 remove_monster(grd->mx, grd->my);
1241 place_monster(grd, nx, ny);
1242 if (newspot && g_at(nx, ny)) {
1243 /* if there's gold already here (most likely from mineralize()),
1244 pick it up now so that guard doesn't later think hero dropped
1245 it and give an inappropriate message */
1247 if (canspotmon(grd))
1249 pline("%s picks up some gold.", Monnam(grd));
1251 pline("%s
\82Í
\8bà
\82ð
\8fE
\82Á
\82½
\81D", Monnam(grd));
1253 newsym(grd->mx, grd->my);
1258 /* Routine when dying or quitting with a vault guard around */
1263 register struct monst *grd = findgd();
1264 long umoney = money_cnt(invent);
1265 struct obj *coins, *nextcoins;
1269 if (!umoney || !grd)
1275 Your("%ld %s goes into the Magic Memory Vault.",
1276 umoney, currency(umoney));
1278 Your("%ld%s
\82Í
\96\82\96@
\82Ì
\8bL
\94O
\91q
\8cÉ
\82É
\93ü
\82Á
\82½
\81D",
1279 umoney, currency(umoney));
1284 if (grd->mpeaceful) /* peaceful guard has no "right" to your gold */
1290 pline("%s remits your gold to the vault.", Monnam(grd));
1292 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8bà
\89Ý
\82ð
\91q
\8cÉ
\82É
\91\97\82Á
\82½
\81D", Monnam(grd));
1293 gx = rooms[EGD(grd)->vroom].lx + rn2(2);
1294 gy = rooms[EGD(grd)->vroom].ly + rn2(2);
1296 Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.",
1297 plname, mons[u.umonster].mname);
1299 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",
1300 mons[u.umonster].mname, plname);
1302 make_grave(gx, gy, buf);
1304 for (coins = invent; coins; coins = nextcoins) {
1305 nextcoins = coins->nobj;
1306 if (objects[coins->otyp].oc_class == COIN_CLASS) {
1308 place_object(coins, gx, gy);
1323 for (obj = invent; obj; obj = obj->nobj)
1324 if (Has_contents(obj))
1325 value += contained_gold(obj);
1326 /* unknown gold stuck inside statues may cause some consternation... */
1331 /* prevent "You hear footsteps.." when inappropriate */
1335 struct monst *grd = findgd();
1337 if (vault_occupied(u.urooms))
1340 return (boolean) (grd == (struct monst *) 0);
1344 vault_gd_watching(activity)
1345 unsigned int activity;
1347 struct monst *guard = findgd();
1349 if (guard && guard->mcansee && m_canseeu(guard)) {
1350 if (activity == GD_EATGOLD || activity == GD_DESTROYGOLD)
1351 EGD(guard)->witness = activity;