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-2020 */
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 if (!rloc(mtmp, TRUE))
91 lev = &levl[fcx][fcy];
92 if (lev->typ == CORR && cansee(fcx, fcy))
94 lev->typ = egrd->fakecorr[fcbeg].ftyp;
95 if (IS_STWALL(lev->typ)) {
96 /* destroy any trap here (pit dug by you, hole dug via
97 wand while levitating or by monster, bear trap or land
98 mine via object, spun web) when spot reverts to stone */
99 if ((trap = t_at(fcx, fcy)) != 0)
101 /* undo scroll/wand/spell of light affecting this spot */
102 if (lev->typ == STONE)
105 map_location(fcx, fcy, 1); /* bypass vision */
106 if (!ACCESSIBLE(lev->typ))
107 block_point(fcx, fcy);
108 vision_full_recalc = 1;
111 if (sawcorridor && !silently)
113 pline_The("corridor disappears.");
115 pline("
\92Ê
\98H
\82Í
\8fÁ
\82¦
\82½
\81D");
116 /* only give encased message if hero is still alive (might get here
117 via paygd() -> mongone() -> grddead() when game is over;
118 died: no message, quit: message) */
119 if (IS_ROCK(levl[u.ux][u.uy].typ) && (Upolyd ? u.mh : u.uhp) > 0
122 You("are encased in rock.");
124 You("
\90Î
\82É
\82Â
\82Â
\82Ü
\82ê
\82½
\81D");
128 /* as a temporary corridor is removed, set stone locations and adjacent
129 spots to unlit; if player used scroll/wand/spell of light while inside
130 the corridor, we don't want the light to reappear if/when a new tunnel
131 goes through the same area */
139 for (i = x - 1; i <= x + 1; ++i)
140 for (j = y - 1; j <= y + 1; ++j) {
144 /* [possible bug: when (i != x || j != y), perhaps we ought
145 to check whether the spot on the far side is lit instead
146 of doing a blanket blackout of adjacent locations] */
147 if (lev->typ == STONE)
148 lev->lit = lev->waslit = 0;
149 /* mark <i,j> as not having been seen from <x,y> */
150 unset_seenv(lev, x, y, i, j);
158 /* it seems you left the corridor - let the guard disappear */
159 if (clear_fcorr(grd, FALSE)) {
160 grd->isgd = 0; /* dmonsfree() should delete this mon */
165 /* move guard--dead to alive--to <0,0> until temporary corridor is removed */
170 /* either guard is dead or will now be treated as if so;
171 monster traversal loops should skip it */
172 if (grd == context.polearm.hitmon)
173 context.polearm.hitmon = 0;
175 remove_monster(grd->mx, grd->my);
176 newsym(grd->mx, grd->my);
177 place_monster(grd, 0, 0);
178 /* [grd->mx,my just got set to 0,0 by place_monster(), so this
179 just sets EGD(grd)->ogx,ogy to 0,0 too; is that what we want?] */
180 EGD(grd)->ogx = grd->mx;
181 EGD(grd)->ogy = grd->my;
185 /* called in mon.c */
190 boolean dispose = clear_fcorr(grd, TRUE);
193 /* destroy guard's gold; drop any other inventory */
194 relobj(grd, 0, FALSE);
197 dispose = clear_fcorr(grd, TRUE);
200 grd->isgd = 0; /* for dmonsfree() */
205 in_fcorridor(grd, x, y)
210 struct egd *egrd = EGD(grd);
212 for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
213 if (x == egrd->fakecorr[fci].fx && y == egrd->fakecorr[fci].fy)
221 register struct monst *mtmp;
223 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
224 if (DEADMONSTER(mtmp))
226 if (mtmp->isgd && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
229 return (struct monst *) 0;
235 if (vault_occupied(u.urooms) && !findgd())
236 u.uinvault = (VAULT_GUARD_TIME - 1);
240 vault_occupied(array)
245 for (ptr = array; *ptr; ptr++)
246 if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
251 /* hero has teleported out of vault while a guard is active */
256 /* only called if caller has checked vault_occupied() and findgd() */
257 if (!grd || !grd->isgd || DEADMONSTER(grd)) {
258 impossible("escaping vault without guard?");
261 /* if carrying gold and arriving anywhere other than next to the guard,
262 set the guard loose */
263 if ((money_cnt(invent) || hidden_gold())
264 && um_dist(grd->mx, grd->my, 1)) {
265 if (grd->mpeaceful) {
266 if (canspotmon(grd)) /* see or sense via telepathy */
268 pline("%s becomes irate.", Monnam(grd));
270 pline("%s
\82Í
\8c\83\93{
\82µ
\82½
\81D", Monnam(grd));
271 grd->mpeaceful = 0; /* bypass setmangry() */
273 /* if arriving outside guard's temporary corridor, give the
274 guard an extra move to deliver message(s) and to teleport
275 out of and remove that corridor */
276 if (!in_fcorridor(grd, u.ux, u.uy))
282 find_guard_dest(guard, rx, ry)
286 register int x, y, dd, lx = 0, ly = 0;
288 for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
289 for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) {
290 if (y < 0 || y > ROWNO - 1)
292 for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) {
293 if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
295 if (x < 1 || x > COLNO - 1)
297 if (guard && ((x == guard->mx && y == guard->my)
298 || (guard->isgd && in_fcorridor(guard, x, y))))
300 if (levl[x][y].typ == CORR) {
301 lx = (x < u.ux) ? x + 1 : (x > u.ux) ? x - 1 : x;
302 ly = (y < u.uy) ? y + 1 : (y > u.uy) ? y - 1 : y;
303 if (levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
314 impossible("Not a single corridor on this level?");
323 int dummy; /* hack to avoid schain botch */
327 int trycount, vaultroom = (int) vault_occupied(u.urooms);
333 vaultroom -= ROOMOFFSET;
336 if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) {
337 /* if time ok and no guard now. */
339 register int x, y, gx, gy;
343 /* first find the goal for the guard */
344 if (!find_guard_dest((struct monst *)0, &rx, &ry))
348 /* next find a good place for a door in the wall */
351 if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */
352 if (levl[x + 1][y].typ == ROOM)
354 else if (levl[x][y + 1].typ == ROOM)
356 else if (levl[x - 1][y].typ == ROOM)
358 else if (levl[x][y - 1].typ == ROOM)
360 else if (levl[x + 1][y + 1].typ == ROOM) {
363 } else if (levl[x - 1][y - 1].typ == ROOM) {
366 } else if (levl[x + 1][y - 1].typ == ROOM) {
369 } else if (levl[x - 1][y + 1].typ == ROOM) {
374 while (levl[x][y].typ == ROOM) {
377 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
378 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
379 if (abs(gx - x) >= abs(gy - y))
384 if (x == u.ux && y == u.uy) {
385 if (levl[x + 1][y].typ == HWALL || levl[x + 1][y].typ == DOOR)
387 else if (levl[x - 1][y].typ == HWALL
388 || levl[x - 1][y].typ == DOOR)
390 else if (levl[x][y + 1].typ == VWALL
391 || levl[x][y + 1].typ == DOOR)
393 else if (levl[x][y - 1].typ == VWALL
394 || levl[x][y - 1].typ == DOOR)
400 /* make something interesting happen */
401 if (!(guard = makemon(&mons[PM_GUARD], x, y, MM_EGD)))
404 guard->mpeaceful = 1;
406 EGD(guard)->gddone = 0;
409 assign_level(&(EGD(guard)->gdlevel), &u.uz);
410 EGD(guard)->vroom = vaultroom;
411 EGD(guard)->warncnt = 0;
413 reset_faint(); /* if fainted - wake up */
414 gsensed = !canspotmon(guard);
417 pline("Suddenly one of the Vault's %s enters!",
418 makeplural(guard->data->mname));
420 pline("
\93Ë
\91R
\81C
\91q
\8cÉ
\82Ì
\94Ô
\95º
\82ª
\93ü
\82Á
\82Ä
\82«
\82½
\81I");
424 pline("Someone else has entered the Vault.");
426 pline("
\92N
\82©
\82ª
\91q
\8cÉ
\82É
\93ü
\82Á
\82Ä
\82«
\82½
\81D");
427 newsym(guard->mx, guard->my);
429 /* can't interrogate hero, don't interrogate engulfer */
432 verbalize("What's going on here?");
434 verbalize("
\82±
\82±
\82Å
\89½
\82ð
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\81H");
437 pline_The("other presence vanishes.");
439 pline("
\91¼
\90l
\82Ì
\8bC
\94z
\82Í
\8fÁ
\82¦
\82½
\81D");
443 if (U_AP_TYPE == M_AP_OBJECT || u.uundetected) {
444 if (U_AP_TYPE == M_AP_OBJECT
445 && youmonst.mappearance != GOLD_PIECE)
448 verbalize("Hey! Who left that %s in here?",
449 mimic_obj_name(&youmonst));
451 verbalize("
\82¨
\82¢
\81I
\82¾
\82ê
\82ª
\82±
\82Ì%s
\82ð
\82±
\82±
\82É
\92u
\82¢
\82Ä
\8ds
\82Á
\82½
\82ñ
\82¾
\81H",
452 mimic_obj_name(&youmonst));
454 /* You're mimicking some object or you're hidden. */
456 pline("Puzzled, %s turns around and leaves.", mhe(guard));
458 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));
462 if (Strangled || is_silent(youmonst.data) || multi < 0) {
463 /* [we ought to record whether this this message has already
464 been given in order to vary it upon repeat visits, but
465 discarding the monster and its egd data renders that hard] */
468 pline("%s huffs and turns to leave.", noit_Monnam(guard));
470 pline("%s
\82Í
\95s
\8b@
\8c\99\82É
\82È
\82Á
\82Ä
\81C
\8b\8e\82Á
\82Ä
\82¢
\82Á
\82½
\81D", noit_Monnam(guard));
473 verbalize("I'll be back when you're ready to speak to me!");
475 verbalize("
\98b
\82¹
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82ç
\96ß
\82Á
\82Ä
\82«
\82Ä
\82â
\82é
\81I");
480 stop_occupation(); /* if occupied, stop it *now* */
489 getlin(Deaf ? "You are required to supply your name. -"
490 : "\"Hello stranger, who are you?\" -", buf);
492 getlin(Deaf ? "
\96¼
\91O
\82ð
\8c¾
\82¤
\82æ
\82¤
\82É
\8b\81\82ß
\82ç
\82ê
\82½
\81D-"
493 : "
\81u
\8c©
\82È
\82¢
\8aç
\82¾
\82È
\81C
\82¨
\82Ü
\82¦
\82Í
\92N
\82¾
\81H
\81v-", buf);
495 (void) mungspaces(buf);
497 } while (!buf[0] && --trycount > 0);
499 } while (!buf[0] && !is_kanji(buf[0]) && --trycount > 0);
502 if (u.ualign.type == A_LAWFUL
503 /* ignore trailing text, in case player includes rank */
504 && strncmpi(buf, plname, (int) strlen(plname)) != 0) {
505 adjalign(-1); /* Liar! */
509 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
510 || !strcmpi(buf, "Creosote")) { /* Discworld */
512 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
513 || !strcmpi(buf, "Creosote") /* Discworld */
514 || !strcmp(buf, "
\83N
\83\8d\83C
\83\
\83X") || !strcmp(buf, "
\83N
\83\8c\83I
\83\
\81[
\83g")) {
516 if (!mvitals[PM_CROESUS].died) {
520 pline("%s waves goodbye.", noit_Monnam(guard));
522 pline("%s
\82Í
\82³
\82æ
\82È
\82ç
\82Æ
\8eè
\82ð
\90U
\82Á
\82½
\81D", noit_Monnam(guard));
526 "Oh, yes, of course. Sorry to have disturbed you.");
528 "
\82¢
\82â
\81C
\82±
\82è
\82á
\81C
\82¦
\81[
\82Æ
\81C
\82¨
\91\9b\82ª
\82¹
\82µ
\82Ü
\82µ
\82½
\81D");
532 setmangry(guard, FALSE);
536 pline("%s mouths something and looks very angry!",
539 pline("%s
\82Í
\89½
\82©
\82ð
\8c¾
\82Á
\82Ä
\82¢
\82é
\81D
\82Æ
\82Ä
\82à
\93{
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81I",
545 "Back from the dead, are you? I'll remedy that!");
548 "
\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");
551 /* don't want guard to waste next turn wielding a weapon */
552 if (!MON_WEP(guard)) {
553 guard->weapon_check = NEED_HTH_WEAPON;
554 (void) mon_wield_item(guard);
561 pline("%s doesn't %srecognize you.", noit_Monnam(guard),
562 (Blind) ? "" : "appear to ");
564 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82±
\82Æ
\82ª
\95ª
\82©
\82ç
\82È
\82¢
\82æ
\82¤
\82¾
\81D", noit_Monnam(guard));
568 verbalize("I don't know you.");
570 verbalize("
\92m
\82ç
\82ñ
\82È
\81D");
571 umoney = money_cnt(invent);
572 if (!umoney && !hidden_gold()) {
575 pline("%s stomps%s.", noit_Monnam(guard),
576 (Blind) ? "" : " and beckons");
578 pline("%s
\82Í
\91«
\82ð
\93¥
\82Ý
\96Â
\82ç
\82µ%s
\82½
\81D", noit_Monnam(guard),
579 (Blind) ? "" : "
\82Ä
\8eè
\8fµ
\82«
\82µ");
583 verbalize("Please follow me.");
585 verbalize("
\8e\84\82Ì
\8cã
\82É
\82Â
\82¢
\82Ä
\82«
\82È
\82³
\82¢
\81D");
591 pline("%s glares at you%s.", noit_Monnam(guard),
592 invent ? "r stuff" : "");
594 pline("%s
\82Í
\82 \82È
\82½%s
\82ð
\82É
\82ç
\82Ý
\82Â
\82¯
\82½
\81D", noit_Monnam(guard),
595 invent ? "
\82Ì
\8e\9d\82¿
\95¨" : "");
599 verbalize("You have hidden gold.");
601 verbalize("
\82Ü
\82¾
\8bà
\89Ý
\82ð
\89B
\82µ
\82Ä
\82é
\82È
\81D");
608 "%s holds out %s palm and beckons with %s other hand.",
609 noit_Monnam(guard), noit_mhis(guard),
613 "%s
\82Í
\95Ð
\8eè
\82ð
\8d·
\82µ
\8fo
\82µ
\81C
\82à
\82¤
\95Ð
\8eè
\82Å
\8eè
\8fµ
\82«
\82µ
\82½
\81D",
619 "Most likely all your gold was stolen from this vault.");
621 "
\91q
\8cÉ
\82©
\82ç
\93\90\82ñ
\82¾
\8bà
\89Ý
\82ª
\82 \82é
\82¾
\82ë
\82¤
\81D");
623 verbalize("Please drop that gold and follow me.");
625 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");
628 EGD(guard)->gdx = gx;
629 EGD(guard)->gdy = gy;
630 EGD(guard)->fcbeg = 0;
631 EGD(guard)->fakecorr[0].fx = x;
632 EGD(guard)->fakecorr[0].fy = y;
633 if (IS_WALL(levl[x][y].typ)) {
634 EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
635 } else { /* the initial guard location is a dug door */
636 int vlt = EGD(guard)->vroom;
637 xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
638 xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
640 if (x == lowx - 1 && y == lowy - 1)
641 EGD(guard)->fakecorr[0].ftyp = TLCORNER;
642 else if (x == hix + 1 && y == lowy - 1)
643 EGD(guard)->fakecorr[0].ftyp = TRCORNER;
644 else if (x == lowx - 1 && y == hiy + 1)
645 EGD(guard)->fakecorr[0].ftyp = BLCORNER;
646 else if (x == hix + 1 && y == hiy + 1)
647 EGD(guard)->fakecorr[0].ftyp = BRCORNER;
648 else if (y == lowy - 1 || y == hiy + 1)
649 EGD(guard)->fakecorr[0].ftyp = HWALL;
650 else if (x == lowx - 1 || x == hix + 1)
651 EGD(guard)->fakecorr[0].ftyp = VWALL;
653 levl[x][y].typ = DOOR;
654 levl[x][y].doormask = D_NODOOR;
655 unblock_point(x, y); /* doesn't block light */
656 EGD(guard)->fcend = 1;
657 EGD(guard)->warncnt = 1;
662 move_gold(gold, vroom)
669 newsym(gold->ox, gold->oy);
670 nx = rooms[vroom].lx + rn2(2);
671 ny = rooms[vroom].ly + rn2(2);
672 place_object(gold, nx, ny);
682 int vlt = EGD(grd)->vroom;
684 xchar lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1,
685 loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1;
689 boolean fixed = FALSE;
690 boolean movedgold = FALSE;
692 for (x = lox; x <= hix; x++)
693 for (y = loy; y <= hiy; y++) {
694 /* if not on the room boundary, skip ahead */
695 if (x != lox && x != hix && y != loy && y != hiy)
698 if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
699 if ((mon = m_at(x, y)) != 0 && mon != grd) {
702 (void) rloc(mon, FALSE);
704 if ((gold = g_at(x, y)) != 0) {
705 move_gold(gold, EGD(grd)->vroom);
708 if ((trap = t_at(x, y)) != 0)
712 (y == loy) ? TLCORNER : (y == hiy) ? BLCORNER : VWALL;
715 (y == loy) ? TRCORNER : (y == hiy) ? BRCORNER : VWALL;
716 else /* not left or right side, must be top or bottom */
718 levl[x][y].typ = typ;
719 levl[x][y].doormask = 0;
721 * hack: player knows walls are restored because of the
722 * message, below, so show this on the screen.
724 tmp_viz = viz_array[y][x];
725 viz_array[y][x] = IN_SIGHT | COULD_SEE;
727 viz_array[y][x] = tmp_viz;
733 if (movedgold || fixed) {
734 if (in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
736 pline("%s whispers an incantation.", noit_Monnam(grd));
738 pline("%s
\82Í
\8eô
\95¶
\82ð
\82³
\82³
\82â
\82¢
\82½
\81D", noit_Monnam(grd));
741 You_hear("a distant chant.");
743 You_hear("
\89\93\95û
\82Å
\82Ì
\8eô
\95¶
\82ð
\95·
\82¢
\82½
\81D");
746 pline("A mysterious force moves the gold into the vault.");
748 pline("
\95s
\8ev
\8bc
\82È
\97Í
\82ª
\8bà
\89Ý
\82ð
\91q
\8cÉ
\82Ö
\89^
\82ñ
\82¾
\81D");
751 pline_The("damaged vault's walls are magically restored!");
753 pline("
\8f\9d\82Â
\82¢
\82½
\91q
\8cÉ
\82Ì
\95Ç
\82Í
\96\82\96@
\82Å
\95\9c\8c³
\82³
\82ê
\82½
\81I");
758 gd_mv_monaway(grd, nx, ny)
759 register struct monst *grd;
762 if (MON_AT(nx, ny) && !(nx == grd->mx && ny == grd->my)) {
765 verbalize("Out of my way, scum!");
767 verbalize("
\96Ú
\82Ì
\91O
\82©
\82ç
\8fÁ
\82¦
\82ë
\81C
\83N
\83\
\82Á
\82½
\82ê
\81I");
768 if (!rloc(m_at(nx, ny), FALSE) || MON_AT(nx, ny))
769 m_into_limbo(m_at(nx, ny));
773 /* have guard pick gold off the floor, possibly moving to the gold's
774 position before message and back to his current spot after */
776 gd_pick_corridor_gold(grd, goldx, goldy)
778 int goldx, goldy; /* <gold->ox, gold->oy> */
782 int gdelta, newdelta, bestdelta, tryct,
783 guardx = grd->mx, guardy = grd->my;
784 boolean under_u = (goldx == u.ux && goldy == u.uy),
785 see_it = cansee(goldx, goldy);
788 /* Grab the gold from between the hero's feet.
789 If guard is two or more steps away; bring him closer first. */
790 gold = g_at(goldx, goldy);
792 impossible("vault guard: no gold at hero's feet?");
795 gdelta = distu(guardx, guardy);
796 if (gdelta > 2 && see_it) { /* skip if player won't see it */
798 bestcc.x = (xchar) guardx, bestcc.y = (xchar) guardy;
801 /* pick an available spot nearest the hero and also try
802 to find the one meeting that criterium which is nearest
803 the guard's current location */
804 if (enexto(&newcc, goldx, goldy, grd->data)) {
805 if ((newdelta = distu(newcc.x, newcc.y)) < bestdelta
806 || (newdelta == bestdelta
807 && dist2(newcc.x, newcc.y, guardx, guardy)
808 < dist2(bestcc.x, bestcc.y, guardx, guardy))) {
809 bestdelta = newdelta;
813 } while (--tryct >= 0);
815 if (bestdelta < gdelta) {
816 remove_monster(guardx, guardy);
817 newsym(guardx, guardy);
818 place_monster(grd, (int) bestcc.x, (int) bestcc.y);
819 newsym(grd->mx, grd->my);
822 obj_extract_self(gold);
823 add_to_minv(grd, gold);
824 newsym(goldx, goldy);
826 /* guard is already at gold's location */
827 } else if (goldx == guardx && goldy == guardy) {
828 mpickgold(grd); /* does a newsym */
830 /* gold is at some third spot, neither guard's nor hero's */
832 /* just for insurance... */
833 gd_mv_monaway(grd, goldx, goldy); /* make room for guard */
834 if (see_it) { /* skip if player won't see the message */
835 remove_monster(grd->mx, grd->my);
836 newsym(grd->mx, grd->my);
837 place_monster(grd, goldx, goldy); /* sets <grd->mx, grd->my> */
839 mpickgold(grd); /* does a newsym */
842 if (see_it) { /* cansee(goldx, goldy) */
843 char monnambuf[BUFSZ];
845 Strcpy(monnambuf, Monnam(grd));
846 if (!strcmpi(monnambuf, "It"))
847 Strcpy(monnambuf, "Someone");
849 pline("%s%s picks up the gold%s.", monnambuf,
850 (grd->mpeaceful && EGD(grd)->warncnt > 5)
851 ? " calms down and" : "",
852 under_u ? " from beneath you" : "");
854 pline("%s
\82Í%s%s
\8bà
\89Ý
\82ð
\8fE
\82Á
\82½
\81D", monnambuf,
855 (grd->mpeaceful && EGD(grd)->warncnt > 5)
856 ? "
\93{
\82è
\82ð
\90Ã
\82ß" : "",
857 under_u ? "
\82 \82È
\82½
\82Ì
\91«
\8c³
\82Ì" : "");
861 /* if guard was moved to get the gold, move him back */
862 if (grd->mx != guardx || grd->my != guardy) {
863 remove_monster(grd->mx, grd->my);
864 newsym(grd->mx, grd->my);
865 place_monster(grd, guardx, guardy);
866 newsym(guardx, guardy);
872 * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died
876 register struct monst *grd;
878 int x, y, nx, ny, m, n;
879 int dx, dy, gx = 0, gy = 0, fci;
882 struct fakecorridor *fcp;
883 register struct egd *egrd = EGD(grd);
885 boolean goldincorridor = FALSE, u_in_vault = FALSE, grd_in_vault = FALSE,
886 disappear_msg_seen = FALSE, semi_dead = DEADMONSTER(grd),
887 u_carry_gold = FALSE, newspot = FALSE, see_guard;
889 if (!on_level(&(egrd->gdlevel), &u.uz))
892 if (semi_dead || !grd->mx || egrd->gddone) {
896 debugpline1("gd_move: %s guard", grd->mpeaceful ? "peaceful" : "hostile");
898 u_in_vault = vault_occupied(u.urooms) ? TRUE : FALSE;
899 grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? TRUE : FALSE;
900 if (!u_in_vault && !grd_in_vault)
903 if (!grd->mpeaceful) {
905 && (grd_in_vault || (in_fcorridor(grd, grd->mx, grd->my)
906 && !in_fcorridor(grd, u.ux, u.uy)))) {
907 (void) rloc(grd, TRUE);
909 if (!in_fcorridor(grd, grd->mx, grd->my))
910 (void) clear_fcorr(grd, TRUE);
913 if (!in_fcorridor(grd, grd->mx, grd->my))
914 (void) clear_fcorr(grd, TRUE);
917 if (abs(egrd->ogx - grd->mx) > 1 || abs(egrd->ogy - grd->my) > 1)
918 return -1; /* teleported guard - treat as monster */
923 verbalize("How dare you %s that gold, scoundrel!",
924 (egrd->witness & GD_EATGOLD) ? "consume" : "destroy");
926 verbalize("
\82æ
\82
\82à
\82Ü
\82 \8bà
\82ð%s
\82à
\82Ì
\82¾
\81C
\88«
\93}
\82ß
\81I",
927 (egrd->witness & GD_EATGOLD) ? "
\8eg
\82Á
\82½" : "
\89ó
\82µ
\82½");
934 umoney = money_cnt(invent);
935 u_carry_gold = umoney > 0L || hidden_gold() > 0L;
936 if (egrd->fcend == 1) {
937 if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
938 if (egrd->warncnt == 3 && !Deaf)
940 verbalize("I repeat, %sfollow me!",
942 ? (!umoney ? "drop that hidden money and "
943 : "drop that money and ")
946 verbalize("
\8cJ
\82è
\95Ô
\82·
\81I%s
\8e\84\82É
\82Â
\82¢
\82Ä
\82±
\82¢
\81I",
948 ? (!umoney ? "
\89B
\82µ
\8e\9d\82Á
\82Ä
\82é
\8bà
\82ð
\92u
\82¢
\82Ä"
949 : "
\8bà
\82ð
\92u
\82¢
\82Ä")
952 if (egrd->warncnt == 7) {
957 verbalize("You've been warned, knave!");
959 verbalize("
\8cx
\8d\90\82Í
\82µ
\82½
\82¼
\81C
\88«
\93}
\82ß
\81I");
961 levl[m][n].typ = egrd->fakecorr[0].ftyp;
966 /* not fair to get mad when (s)he's fainted or paralyzed */
967 if (!is_fainted() && multi >= 0)
973 if (u_carry_gold) { /* player teleported */
976 (void) rloc(grd, TRUE);
977 levl[m][n].typ = egrd->fakecorr[0].ftyp;
981 if (!cansee(grd->mx, grd->my) || !mon_visible(grd))
984 m_carrying(grd, TIN_WHISTLE)
985 ? "the shrill sound of a guard's whistle"
988 You_hear("%s
\82ð
\95·
\82¢
\82½
\81D",
989 m_carrying(grd, TIN_WHISTLE)
990 ? "
\94Ô
\95º
\82Ì
\89s
\82¢
\93J
\82Ì
\89¹"
991 : "
\93{
\82è
\82Ì
\8b©
\82Ñ");
995 You(um_dist(grd->mx, grd->my, 2)
996 ? "see %s approaching."
997 : "are confronted by %s.",
998 /* "an angry guard" */
999 x_monnam(grd, ARTICLE_A, "angry", 0, FALSE));
1001 You(um_dist(grd->mx, grd->my, 2)
1002 ? "%s
\82ª
\8bß
\82Ã
\82¢
\82Ä
\82
\82é
\82Ì
\82ð
\8c©
\82½
\81D"
1003 : "%s
\82Æ
\91Î
\9b³
\82µ
\82½
\81D",
1004 x_monnam(grd, ARTICLE_A, "
\93{
\82Á
\82½", 0, FALSE));
1010 verbalize("Well, begone.");
1012 verbalize("
\97§
\82¿
\8b\8e\82ê
\81D");
1019 if (egrd->fcend > 1) {
1020 if (egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my)
1021 && !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy)
1022 && levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
1023 == egrd->fakecorr[0].ftyp) {
1025 pline("%s, confused, disappears.", noit_Monnam(grd));
1027 pline("%s
\82Í
\8d¬
\97\90\82µ
\81C
\8fÁ
\82¦
\82½
\81D", noit_Monnam(grd));
1028 disappear_msg_seen = TRUE;
1031 if (u_carry_gold && (in_fcorridor(grd, u.ux, u.uy)
1032 /* cover a 'blind' spot */
1033 || (egrd->fcend > 1 && u_in_vault))) {
1038 if (egrd->warncnt < 6) {
1043 pline("%s holds out %s palm demandingly!",
1044 noit_Monnam(grd), noit_mhis(grd));
1046 pline("%s
\82Í
\8cµ
\82µ
\82¢
\92²
\8eq
\82Å
\8eè
\82Ì
\82Ð
\82ç
\82ð
\8d·
\82µ
\8fo
\82µ
\82½
\81I",
1051 verbalize("Drop all your gold, scoundrel!");
1053 verbalize("
\8bà
\82ð
\91S
\95\94\92u
\82¢
\82Ä
\82ä
\82¯
\81C
\82È
\82ç
\82¸
\82à
\82Ì
\81I");
1060 pline("%s rubs %s hands with enraged delight!",
1061 noit_Monnam(grd), noit_mhis(grd));
1063 pline("%s
\82Í
\93{
\82è
\82È
\82ª
\82ç
\8eè
\82ð
\82·
\82è
\82 \82í
\82¹
\82½
\81I",
1068 verbalize("So be it, rogue!");
1070 verbalize("
\93\90\90l
\82ß
\81I");
1077 for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
1078 if (g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) {
1079 m = egrd->fakecorr[fci].fx;
1080 n = egrd->fakecorr[fci].fy;
1081 goldincorridor = TRUE;
1084 /* new gold can appear if it was embedded in stone and hero kicks it
1085 (on even via wish and drop) so don't assume hero has been warned */
1086 if (goldincorridor && !egrd->gddone) {
1087 gd_pick_corridor_gold(grd, m, n);
1088 if (!grd->mpeaceful)
1093 if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
1094 if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow
1095 && !(u.ustuck && !sticks(youmonst.data)))
1097 verbalize("Move along!");
1099 verbalize("
\97£
\82ê
\82é
\82È
\81I");
1101 return 0; /* didn't move */
1109 /* look around (hor & vert only) for accessible places */
1110 for (nx = x - 1; nx <= x + 1; nx++)
1111 for (ny = y - 1; ny <= y + 1; ny++) {
1112 if ((nx == x || ny == y) && (nx != x || ny != y)
1114 typ = (crm = &levl[nx][ny])->typ;
1115 if (!IS_STWALL(typ) && !IS_POOL(typ)) {
1116 if (in_fcorridor(grd, nx, ny))
1119 if (*in_rooms(nx, ny, VAULT))
1122 /* seems we found a good place to leave him alone */
1124 if (ACCESSIBLE(typ))
1132 crm->typ = (typ == SCORR) ? CORR : DOOR;
1134 if (crm->typ == DOOR)
1135 crm->doormask = D_NODOOR;
1147 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
1148 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
1149 if (abs(gx - x) >= abs(gy - y))
1154 while ((typ = (crm = &levl[nx][ny])->typ) != STONE) {
1155 /* in view of the above we must have IS_WALL(typ) or typ == POOL */
1156 /* must be a wall here */
1157 if (isok(nx + nx - x, ny + ny - y) && !IS_POOL(typ)
1158 && IS_ROOM(levl[nx + nx - x][ny + ny - y].typ)) {
1160 crm->doormask = D_NODOOR;
1163 if (dy && nx != x) {
1168 if (dx && ny != y) {
1174 /* I don't like this, but ... */
1177 crm->doormask = D_NODOOR;
1185 unblock_point(nx, ny); /* doesn't block light */
1189 if ((nx != gx || ny != gy) || (grd->mx != gx || grd->my != gy)) {
1190 fcp = &(egrd->fakecorr[egrd->fcend]);
1191 if (egrd->fcend++ == FCSIZ)
1192 panic("fakecorr overflow");
1196 } else if (!egrd->gddone) {
1197 /* We're stuck, so try to find a new destination. */
1198 if (!find_guard_dest(grd, &egrd->gdx, &egrd->gdy)
1199 || (egrd->gdx == gx && egrd->gdy == gy)) {
1201 pline("%s, confused, disappears.", Monnam(grd));
1203 pline("%s
\82Í
\8d¬
\97\90\82µ
\81C
\8fÁ
\82¦
\82½
\81D", Monnam(grd));
1204 disappear_msg_seen = TRUE;
1210 gd_mv_monaway(grd, nx, ny);
1212 /* The following is a kludge. We need to keep */
1213 /* the guard around in order to be able to make */
1214 /* the fake corridor disappear as the player */
1215 /* moves out of it, but we also need the guard */
1216 /* out of the way. We send the guard to never- */
1217 /* never land. We set ogx ogy to mx my in order */
1218 /* to avoid a check at the top of this function. */
1219 /* At the end of the process, the guard is killed */
1220 /* in restfakecorr(). */
1222 x = grd->mx, y = grd->my;
1223 see_guard = canspotmon(grd);
1224 parkguard(grd); /* move to <0,0> */
1227 debugpline2("gd_move: %scleanup%s",
1228 grd->isgd ? "" : "final ",
1229 grd->isgd ? " attempt" : "");
1230 if (!semi_dead && (in_fcorridor(grd, u.ux, u.uy) || cansee(x, y))) {
1231 if (!disappear_msg_seen && see_guard)
1233 pline("Suddenly, %s disappears.", noit_mon_nam(grd));
1235 pline("
\93Ë
\91R
\81C%s
\82Í
\8fÁ
\82¦
\82½
\81D", noit_mon_nam(grd));
1240 egrd->ogx = grd->mx; /* update old positions */
1241 egrd->ogy = grd->my;
1242 remove_monster(grd->mx, grd->my);
1243 place_monster(grd, nx, ny);
1244 if (newspot && g_at(nx, ny)) {
1245 /* if there's gold already here (most likely from mineralize()),
1246 pick it up now so that guard doesn't later think hero dropped
1247 it and give an inappropriate message */
1249 if (canspotmon(grd))
1251 pline("%s picks up some gold.", Monnam(grd));
1253 pline("%s
\82Í
\8bà
\82ð
\8fE
\82Á
\82½
\81D", Monnam(grd));
1255 newsym(grd->mx, grd->my);
1260 /* Routine when dying or quitting with a vault guard around */
1265 register struct monst *grd = findgd();
1266 long umoney = money_cnt(invent);
1267 struct obj *coins, *nextcoins;
1271 if (!umoney || !grd)
1277 Your("%ld %s goes into the Magic Memory Vault.",
1278 umoney, currency(umoney));
1280 Your("%ld%s
\82Í
\96\82\96@
\82Ì
\8bL
\94O
\91q
\8cÉ
\82É
\93ü
\82Á
\82½
\81D",
1281 umoney, currency(umoney));
1286 if (grd->mpeaceful) /* peaceful guard has no "right" to your gold */
1292 pline("%s remits your gold to the vault.", Monnam(grd));
1294 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8bà
\89Ý
\82ð
\91q
\8cÉ
\82É
\91\97\82Á
\82½
\81D", Monnam(grd));
1295 gx = rooms[EGD(grd)->vroom].lx + rn2(2);
1296 gy = rooms[EGD(grd)->vroom].ly + rn2(2);
1298 Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.",
1299 plname, mons[u.umonster].mname);
1301 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",
1302 mons[u.umonster].mname, plname);
1304 make_grave(gx, gy, buf);
1306 for (coins = invent; coins; coins = nextcoins) {
1307 nextcoins = coins->nobj;
1308 if (objects[coins->otyp].oc_class == COIN_CLASS) {
1310 place_object(coins, gx, gy);
1325 for (obj = invent; obj; obj = obj->nobj)
1326 if (Has_contents(obj))
1327 value += contained_gold(obj);
1328 /* unknown gold stuck inside statues may cause some consternation... */
1333 /* prevent "You hear footsteps.." when inappropriate */
1337 struct monst *grd = findgd();
1339 if (vault_occupied(u.urooms))
1342 return (boolean) (grd == (struct monst *) 0);
1346 vault_gd_watching(activity)
1347 unsigned int activity;
1349 struct monst *guard = findgd();
1351 if (guard && guard->mcansee && m_canseeu(guard)) {
1352 if (activity == GD_EATGOLD || activity == GD_DESTROYGOLD)
1353 EGD(guard)->witness = activity;