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 */
266 pline("%s becomes irate.", Monnam(grd));
267 grd->mpeaceful = 0; /* bypass setmangry() */
269 /* if arriving outside guard's temporary corridor, give the
270 guard an extra move to deliver message(s) and to teleport
271 out of and remove that corridor */
272 if (!in_fcorridor(grd, u.ux, u.uy))
278 find_guard_dest(guard, rx, ry)
282 register int x, y, dd, lx = 0, ly = 0;
284 for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
285 for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) {
286 if (y < 0 || y > ROWNO - 1)
288 for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) {
289 if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd)
291 if (x < 1 || x > COLNO - 1)
293 if (guard && ((x == guard->mx && y == guard->my)
294 || (guard->isgd && in_fcorridor(guard, x, y))))
296 if (levl[x][y].typ == CORR) {
297 lx = (x < u.ux) ? x + 1 : (x > u.ux) ? x - 1 : x;
298 ly = (y < u.uy) ? y + 1 : (y > u.uy) ? y - 1 : y;
299 if (levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
310 impossible("Not a single corridor on this level?");
319 int dummy; /* hack to avoid schain botch */
323 int trycount, vaultroom = (int) vault_occupied(u.urooms);
329 vaultroom -= ROOMOFFSET;
332 if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) {
333 /* if time ok and no guard now. */
335 register int x, y, gx, gy;
339 /* first find the goal for the guard */
340 if (!find_guard_dest((struct monst *)0, &rx, &ry))
344 /* next find a good place for a door in the wall */
347 if (levl[x][y].typ != ROOM) { /* player dug a door and is in it */
348 if (levl[x + 1][y].typ == ROOM)
350 else if (levl[x][y + 1].typ == ROOM)
352 else if (levl[x - 1][y].typ == ROOM)
354 else if (levl[x][y - 1].typ == ROOM)
356 else if (levl[x + 1][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) {
370 while (levl[x][y].typ == ROOM) {
373 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
374 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
375 if (abs(gx - x) >= abs(gy - y))
380 if (x == u.ux && y == u.uy) {
381 if (levl[x + 1][y].typ == HWALL || levl[x + 1][y].typ == DOOR)
383 else if (levl[x - 1][y].typ == HWALL
384 || levl[x - 1][y].typ == DOOR)
386 else if (levl[x][y + 1].typ == VWALL
387 || levl[x][y + 1].typ == DOOR)
389 else if (levl[x][y - 1].typ == VWALL
390 || levl[x][y - 1].typ == DOOR)
396 /* make something interesting happen */
397 if (!(guard = makemon(&mons[PM_GUARD], x, y, MM_EGD)))
400 guard->mpeaceful = 1;
402 EGD(guard)->gddone = 0;
405 assign_level(&(EGD(guard)->gdlevel), &u.uz);
406 EGD(guard)->vroom = vaultroom;
407 EGD(guard)->warncnt = 0;
409 reset_faint(); /* if fainted - wake up */
410 gsensed = !canspotmon(guard);
413 pline("Suddenly one of the Vault's %s enters!",
414 makeplural(guard->data->mname));
416 pline("
\93Ë
\91R
\81C
\91q
\8cÉ
\82Ì
\94Ô
\95º
\82ª
\93ü
\82Á
\82Ä
\82«
\82½
\81I");
420 pline("Someone else has entered the Vault.");
422 pline("
\92N
\82©
\82ª
\91q
\8cÉ
\82É
\93ü
\82Á
\82Ä
\82«
\82½
\81D");
423 newsym(guard->mx, guard->my);
425 /* can't interrogate hero, don't interrogate engulfer */
428 verbalize("What's going on here?");
430 verbalize("
\82±
\82±
\82Å
\89½
\82ð
\82µ
\82Ä
\82¢
\82é
\82ñ
\82¾
\81H");
433 pline_The("other presence vanishes.");
435 pline("
\91¼
\90l
\82Ì
\8bC
\94z
\82Í
\8fÁ
\82¦
\82½
\81D");
439 if (U_AP_TYPE == M_AP_OBJECT || u.uundetected) {
440 if (U_AP_TYPE == M_AP_OBJECT
441 && youmonst.mappearance != GOLD_PIECE)
444 verbalize("Hey! Who left that %s in here?",
445 mimic_obj_name(&youmonst));
447 verbalize("
\82¨
\82¢
\81I
\82¾
\82ê
\82ª
\82±
\82Ì%s
\82ð
\82±
\82±
\82É
\92u
\82¢
\82Ä
\8ds
\82Á
\82½
\82ñ
\82¾
\81H",
448 mimic_obj_name(&youmonst));
450 /* You're mimicking some object or you're hidden. */
452 pline("Puzzled, %s turns around and leaves.", mhe(guard));
454 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));
458 if (Strangled || is_silent(youmonst.data) || multi < 0) {
459 /* [we ought to record whether this this message has already
460 been given in order to vary it upon repeat visits, but
461 discarding the monster and its egd data renders that hard] */
464 pline("%s huffs and turns to leave.", noit_Monnam(guard));
466 pline("%s
\82Í
\95s
\8b@
\8c\99\82É
\82È
\82Á
\82Ä
\81C
\8b\8e\82Á
\82Ä
\82¢
\82Á
\82½
\81D", noit_Monnam(guard));
469 verbalize("I'll be back when you're ready to speak to me!");
471 verbalize("
\98b
\82¹
\82é
\82æ
\82¤
\82É
\82È
\82Á
\82½
\82ç
\96ß
\82Á
\82Ä
\82«
\82Ä
\82â
\82é
\81I");
476 stop_occupation(); /* if occupied, stop it *now* */
485 getlin(Deaf ? "You are required to supply your name. -"
486 : "\"Hello stranger, who are you?\" -", buf);
488 getlin(Deaf ? "
\96¼
\91O
\82ð
\8c¾
\82¤
\82æ
\82¤
\82É
\8b\81\82ß
\82ç
\82ê
\82½
\81D-"
489 : "
\81u
\8c©
\82È
\82¢
\8aç
\82¾
\82È
\81C
\82¨
\82Ü
\82¦
\82Í
\92N
\82¾
\81H
\81v-", buf);
491 (void) mungspaces(buf);
493 } while (!buf[0] && --trycount > 0);
495 } while (!buf[0] && !is_kanji(buf[0]) && --trycount > 0);
498 if (u.ualign.type == A_LAWFUL
499 /* ignore trailing text, in case player includes rank */
500 && strncmpi(buf, plname, (int) strlen(plname)) != 0) {
501 adjalign(-1); /* Liar! */
505 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
506 || !strcmpi(buf, "Creosote")) { /* Discworld */
508 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
509 || !strcmpi(buf, "Creosote") /* Discworld */
510 || !strcmp(buf, "
\83N
\83\8d\83C
\83\
\83X") || !strcmp(buf, "
\83N
\83\8c\83I
\83\
\81[
\83g")) {
512 if (!mvitals[PM_CROESUS].died) {
516 pline("%s waves goodbye.", noit_Monnam(guard));
518 pline("%s
\82Í
\82³
\82æ
\82È
\82ç
\82Æ
\8eè
\82ð
\90U
\82Á
\82½
\81D", noit_Monnam(guard));
522 "Oh, yes, of course. Sorry to have disturbed you.");
524 "
\82¢
\82â
\81C
\82±
\82è
\82á
\81C
\82¦
\81[
\82Æ
\81C
\82¨
\91\9b\82ª
\82¹
\82µ
\82Ü
\82µ
\82½
\81D");
528 setmangry(guard, FALSE);
532 pline("%s mouths something and looks very angry!",
535 pline("%s
\82Í
\89½
\82©
\82ð
\8c¾
\82Á
\82Ä
\82¢
\82é
\81D
\82Æ
\82Ä
\82à
\93{
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81I",
541 "Back from the dead, are you? I'll remedy that!");
544 "
\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");
547 /* don't want guard to waste next turn wielding a weapon */
548 if (!MON_WEP(guard)) {
549 guard->weapon_check = NEED_HTH_WEAPON;
550 (void) mon_wield_item(guard);
557 pline("%s doesn't %srecognize you.", noit_Monnam(guard),
558 (Blind) ? "" : "appear to ");
560 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\82±
\82Æ
\82ª
\95ª
\82©
\82ç
\82È
\82¢
\82æ
\82¤
\82¾
\81D", noit_Monnam(guard));
564 verbalize("I don't know you.");
566 verbalize("
\92m
\82ç
\82ñ
\82È
\81D");
567 umoney = money_cnt(invent);
568 if (!umoney && !hidden_gold()) {
571 pline("%s stomps%s.", noit_Monnam(guard),
572 (Blind) ? "" : " and beckons");
574 pline("%s
\82Í
\91«
\82ð
\93¥
\82Ý
\96Â
\82ç
\82µ%s
\82½
\81D", noit_Monnam(guard),
575 (Blind) ? "" : "
\82Ä
\8eè
\8fµ
\82«
\82µ");
579 verbalize("Please follow me.");
581 verbalize("
\8e\84\82Ì
\8cã
\82É
\82Â
\82¢
\82Ä
\82«
\82È
\82³
\82¢
\81D");
587 pline("%s glares at you%s.", noit_Monnam(guard),
588 invent ? "r stuff" : "");
590 pline("%s
\82Í
\82 \82È
\82½%s
\82ð
\82É
\82ç
\82Ý
\82Â
\82¯
\82½
\81D", noit_Monnam(guard),
591 invent ? "
\82Ì
\8e\9d\82¿
\95¨" : "");
595 verbalize("You have hidden gold.");
597 verbalize("
\82Ü
\82¾
\8bà
\89Ý
\82ð
\89B
\82µ
\82Ä
\82é
\82È
\81D");
604 "%s holds out %s palm and beckons with %s other hand.",
605 noit_Monnam(guard), noit_mhis(guard),
609 "%s
\82Í
\95Ð
\8eè
\82ð
\8d·
\82µ
\8fo
\82µ
\81C
\82à
\82¤
\95Ð
\8eè
\82Å
\8eè
\8fµ
\82«
\82µ
\82½
\81D",
615 "Most likely all your gold was stolen from this vault.");
617 "
\91q
\8cÉ
\82©
\82ç
\93\90\82ñ
\82¾
\8bà
\89Ý
\82ª
\82 \82é
\82¾
\82ë
\82¤
\81D");
619 verbalize("Please drop that gold and follow me.");
621 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");
624 EGD(guard)->gdx = gx;
625 EGD(guard)->gdy = gy;
626 EGD(guard)->fcbeg = 0;
627 EGD(guard)->fakecorr[0].fx = x;
628 EGD(guard)->fakecorr[0].fy = y;
629 if (IS_WALL(levl[x][y].typ)) {
630 EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
631 } else { /* the initial guard location is a dug door */
632 int vlt = EGD(guard)->vroom;
633 xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
634 xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
636 if (x == lowx - 1 && y == lowy - 1)
637 EGD(guard)->fakecorr[0].ftyp = TLCORNER;
638 else if (x == hix + 1 && y == lowy - 1)
639 EGD(guard)->fakecorr[0].ftyp = TRCORNER;
640 else if (x == lowx - 1 && y == hiy + 1)
641 EGD(guard)->fakecorr[0].ftyp = BLCORNER;
642 else if (x == hix + 1 && y == hiy + 1)
643 EGD(guard)->fakecorr[0].ftyp = BRCORNER;
644 else if (y == lowy - 1 || y == hiy + 1)
645 EGD(guard)->fakecorr[0].ftyp = HWALL;
646 else if (x == lowx - 1 || x == hix + 1)
647 EGD(guard)->fakecorr[0].ftyp = VWALL;
649 levl[x][y].typ = DOOR;
650 levl[x][y].doormask = D_NODOOR;
651 unblock_point(x, y); /* doesn't block light */
652 EGD(guard)->fcend = 1;
653 EGD(guard)->warncnt = 1;
658 move_gold(gold, vroom)
665 newsym(gold->ox, gold->oy);
666 nx = rooms[vroom].lx + rn2(2);
667 ny = rooms[vroom].ly + rn2(2);
668 place_object(gold, nx, ny);
678 int vlt = EGD(grd)->vroom;
680 xchar lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1,
681 loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1;
685 boolean fixed = FALSE;
686 boolean movedgold = FALSE;
688 for (x = lox; x <= hix; x++)
689 for (y = loy; y <= hiy; y++) {
690 /* if not on the room boundary, skip ahead */
691 if (x != lox && x != hix && y != loy && y != hiy)
694 if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
695 if ((mon = m_at(x, y)) != 0 && mon != grd) {
698 (void) rloc(mon, FALSE);
700 if ((gold = g_at(x, y)) != 0) {
701 move_gold(gold, EGD(grd)->vroom);
704 if ((trap = t_at(x, y)) != 0)
708 (y == loy) ? TLCORNER : (y == hiy) ? BLCORNER : VWALL;
711 (y == loy) ? TRCORNER : (y == hiy) ? BRCORNER : VWALL;
712 else /* not left or right side, must be top or bottom */
714 levl[x][y].typ = typ;
715 levl[x][y].doormask = 0;
717 * hack: player knows walls are restored because of the
718 * message, below, so show this on the screen.
720 tmp_viz = viz_array[y][x];
721 viz_array[y][x] = IN_SIGHT | COULD_SEE;
723 viz_array[y][x] = tmp_viz;
729 if (movedgold || fixed) {
730 if (in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
732 pline("%s whispers an incantation.", noit_Monnam(grd));
734 pline("%s
\82Í
\8eô
\95¶
\82ð
\82³
\82³
\82â
\82¢
\82½
\81D", noit_Monnam(grd));
737 You_hear("a distant chant.");
739 You_hear("
\89\93\95û
\82Å
\82Ì
\8eô
\95¶
\82ð
\95·
\82¢
\82½
\81D");
742 pline("A mysterious force moves the gold into the vault.");
744 pline("
\95s
\8ev
\8bc
\82È
\97Í
\82ª
\8bà
\89Ý
\82ð
\91q
\8cÉ
\82Ö
\89^
\82ñ
\82¾
\81D");
747 pline_The("damaged vault's walls are magically restored!");
749 pline("
\8f\9d\82Â
\82¢
\82½
\91q
\8cÉ
\82Ì
\95Ç
\82Í
\96\82\96@
\82Å
\95\9c\8c³
\82³
\82ê
\82½
\81I");
754 gd_mv_monaway(grd, nx, ny)
755 register struct monst *grd;
758 if (MON_AT(nx, ny) && !(nx == grd->mx && ny == grd->my)) {
761 verbalize("Out of my way, scum!");
763 verbalize("
\96Ú
\82Ì
\91O
\82©
\82ç
\8fÁ
\82¦
\82ë
\81C
\83N
\83\
\82Á
\82½
\82ê
\81I");
764 if (!rloc(m_at(nx, ny), FALSE) || MON_AT(nx, ny))
765 m_into_limbo(m_at(nx, ny));
769 /* have guard pick gold off the floor, possibly moving to the gold's
770 position before message and back to his current spot after */
772 gd_pick_corridor_gold(grd, goldx, goldy)
774 int goldx, goldy; /* <gold->ox, gold->oy> */
778 int gdelta, newdelta, bestdelta, tryct,
779 guardx = grd->mx, guardy = grd->my;
780 boolean under_u = (goldx == u.ux && goldy == u.uy),
781 see_it = cansee(goldx, goldy);
784 /* Grab the gold from between the hero's feet.
785 If guard is two or more steps away; bring him closer first. */
786 gold = g_at(goldx, goldy);
788 impossible("vault guard: no gold at hero's feet?");
791 gdelta = distu(guardx, guardy);
792 if (gdelta > 2 && see_it) { /* skip if player won't see it */
794 bestcc.x = (xchar) guardx, bestcc.y = (xchar) guardy;
797 /* pick an available spot nearest the hero and also try
798 to find the one meeting that criterium which is nearest
799 the guard's current location */
800 if (enexto(&newcc, goldx, goldy, grd->data)) {
801 if ((newdelta = distu(newcc.x, newcc.y)) < bestdelta
802 || (newdelta == bestdelta
803 && dist2(newcc.x, newcc.y, guardx, guardy)
804 < dist2(bestcc.x, bestcc.y, guardx, guardy))) {
805 bestdelta = newdelta;
809 } while (--tryct >= 0);
811 if (bestdelta < gdelta) {
812 remove_monster(guardx, guardy);
813 newsym(guardx, guardy);
814 place_monster(grd, (int) bestcc.x, (int) bestcc.y);
815 newsym(grd->mx, grd->my);
818 obj_extract_self(gold);
819 add_to_minv(grd, gold);
820 newsym(goldx, goldy);
822 /* guard is already at gold's location */
823 } else if (goldx == guardx && goldy == guardy) {
824 mpickgold(grd); /* does a newsym */
826 /* gold is at some third spot, neither guard's nor hero's */
828 /* just for insurance... */
829 gd_mv_monaway(grd, goldx, goldy); /* make room for guard */
830 if (see_it) { /* skip if player won't see the message */
831 remove_monster(grd->mx, grd->my);
832 newsym(grd->mx, grd->my);
833 place_monster(grd, goldx, goldy); /* sets <grd->mx, grd->my> */
835 mpickgold(grd); /* does a newsym */
838 if (see_it) { /* cansee(goldx, goldy) */
839 char monnambuf[BUFSZ];
841 Strcpy(monnambuf, Monnam(grd));
842 if (!strcmpi(monnambuf, "It"))
843 Strcpy(monnambuf, "Someone");
845 pline("%s%s picks up the gold%s.", monnambuf,
846 (grd->mpeaceful && EGD(grd)->warncnt > 5)
847 ? " calms down and" : "",
848 under_u ? " from beneath you" : "");
850 pline("%s
\82Í%s%s
\8bà
\89Ý
\82ð
\8fE
\82Á
\82½
\81D", monnambuf,
851 (grd->mpeaceful && EGD(grd)->warncnt > 5)
852 ? "
\93{
\82è
\82ð
\90Ã
\82ß" : "",
853 under_u ? "
\82 \82È
\82½
\82Ì
\91«
\8c³
\82Ì" : "");
857 /* if guard was moved to get the gold, move him back */
858 if (grd->mx != guardx || grd->my != guardy) {
859 remove_monster(grd->mx, grd->my);
860 newsym(grd->mx, grd->my);
861 place_monster(grd, guardx, guardy);
862 newsym(guardx, guardy);
868 * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died
872 register struct monst *grd;
874 int x, y, nx, ny, m, n;
875 int dx, dy, gx = 0, gy = 0, fci;
878 struct fakecorridor *fcp;
879 register struct egd *egrd = EGD(grd);
881 boolean goldincorridor = FALSE, u_in_vault = FALSE, grd_in_vault = FALSE,
882 disappear_msg_seen = FALSE, semi_dead = DEADMONSTER(grd),
883 u_carry_gold = FALSE, newspot = FALSE, see_guard;
885 if (!on_level(&(egrd->gdlevel), &u.uz))
888 if (semi_dead || !grd->mx || egrd->gddone) {
892 debugpline1("gd_move: %s guard", grd->mpeaceful ? "peaceful" : "hostile");
894 u_in_vault = vault_occupied(u.urooms) ? TRUE : FALSE;
895 grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? TRUE : FALSE;
896 if (!u_in_vault && !grd_in_vault)
899 if (!grd->mpeaceful) {
901 && (grd_in_vault || (in_fcorridor(grd, grd->mx, grd->my)
902 && !in_fcorridor(grd, u.ux, u.uy)))) {
903 (void) rloc(grd, FALSE);
905 (void) clear_fcorr(grd, TRUE);
908 if (!in_fcorridor(grd, grd->mx, grd->my))
909 (void) clear_fcorr(grd, TRUE);
912 if (abs(egrd->ogx - grd->mx) > 1 || abs(egrd->ogy - grd->my) > 1)
913 return -1; /* teleported guard - treat as monster */
918 verbalize("How dare you %s that gold, scoundrel!",
919 (egrd->witness & GD_EATGOLD) ? "consume" : "destroy");
921 verbalize("
\82æ
\82
\82à
\82Ü
\82 \8bà
\82ð%s
\82à
\82Ì
\82¾
\81C
\88«
\93}
\82ß
\81I",
922 (egrd->witness & GD_EATGOLD) ? "
\8eg
\82Á
\82½" : "
\89ó
\82µ
\82½");
929 umoney = money_cnt(invent);
930 u_carry_gold = umoney > 0L || hidden_gold() > 0L;
931 if (egrd->fcend == 1) {
932 if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
933 if (egrd->warncnt == 3 && !Deaf)
935 verbalize("I repeat, %sfollow me!",
937 ? (!umoney ? "drop that hidden money and "
938 : "drop that money and ")
941 verbalize("
\8cJ
\82è
\95Ô
\82·
\81I%s
\8e\84\82É
\82Â
\82¢
\82Ä
\82±
\82¢
\81I",
943 ? (!umoney ? "
\89B
\82µ
\8e\9d\82Á
\82Ä
\82é
\8bà
\82ð
\92u
\82¢
\82Ä"
944 : "
\8bà
\82ð
\92u
\82¢
\82Ä")
947 if (egrd->warncnt == 7) {
952 verbalize("You've been warned, knave!");
954 verbalize("
\8cx
\8d\90\82Í
\82µ
\82½
\82¼
\81C
\88«
\93}
\82ß
\81I");
956 levl[m][n].typ = egrd->fakecorr[0].ftyp;
961 /* not fair to get mad when (s)he's fainted or paralyzed */
962 if (!is_fainted() && multi >= 0)
968 if (u_carry_gold) { /* player teleported */
971 (void) rloc(grd, TRUE);
972 levl[m][n].typ = egrd->fakecorr[0].ftyp;
976 if (!cansee(grd->mx, grd->my) || !mon_visible(grd))
979 m_carrying(grd, TIN_WHISTLE)
980 ? "the shrill sound of a guard's whistle"
983 You_hear("%s
\82ð
\95·
\82¢
\82½
\81D",
984 m_carrying(grd, TIN_WHISTLE)
985 ? "
\94Ô
\95º
\82Ì
\89s
\82¢
\93J
\82Ì
\89¹"
986 : "
\93{
\82è
\82Ì
\8b©
\82Ñ");
990 You(um_dist(grd->mx, grd->my, 2)
991 ? "see %s approaching."
992 : "are confronted by %s.",
993 /* "an angry guard" */
994 x_monnam(grd, ARTICLE_A, "angry", 0, FALSE));
996 You(um_dist(grd->mx, grd->my, 2)
997 ? "%s
\82ª
\8bß
\82Ã
\82¢
\82Ä
\82
\82é
\82Ì
\82ð
\8c©
\82½
\81D"
998 : "%s
\82Æ
\91Î
\9b³
\82µ
\82½
\81D",
999 x_monnam(grd, ARTICLE_A, "
\93{
\82Á
\82½", 0, FALSE));
1005 verbalize("Well, begone.");
1007 verbalize("
\97§
\82¿
\8b\8e\82ê
\81D");
1014 if (egrd->fcend > 1) {
1015 if (egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my)
1016 && !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy)
1017 && levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
1018 == egrd->fakecorr[0].ftyp) {
1020 pline("%s, confused, disappears.", noit_Monnam(grd));
1022 pline("%s
\82Í
\8d¬
\97\90\82µ
\81C
\8fÁ
\82¦
\82½
\81D", noit_Monnam(grd));
1023 disappear_msg_seen = TRUE;
1026 if (u_carry_gold && (in_fcorridor(grd, u.ux, u.uy)
1027 /* cover a 'blind' spot */
1028 || (egrd->fcend > 1 && u_in_vault))) {
1033 if (egrd->warncnt < 6) {
1038 pline("%s holds out %s palm demandingly!",
1039 noit_Monnam(grd), noit_mhis(grd));
1041 pline("%s
\82Í
\8cµ
\82µ
\82¢
\92²
\8eq
\82Å
\8eè
\82Ì
\82Ð
\82ç
\82ð
\8d·
\82µ
\8fo
\82µ
\82½
\81I",
1046 verbalize("Drop all your gold, scoundrel!");
1048 verbalize("
\8bà
\82ð
\91S
\95\94\92u
\82¢
\82Ä
\82ä
\82¯
\81C
\82È
\82ç
\82¸
\82à
\82Ì
\81I");
1055 pline("%s rubs %s hands with enraged delight!",
1056 noit_Monnam(grd), noit_mhis(grd));
1058 pline("%s
\82Í
\93{
\82è
\82È
\82ª
\82ç
\8eè
\82ð
\82·
\82è
\82 \82í
\82¹
\82½
\81I",
1063 verbalize("So be it, rogue!");
1065 verbalize("
\93\90\90l
\82ß
\81I");
1072 for (fci = egrd->fcbeg; fci < egrd->fcend; fci++)
1073 if (g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)) {
1074 m = egrd->fakecorr[fci].fx;
1075 n = egrd->fakecorr[fci].fy;
1076 goldincorridor = TRUE;
1079 /* new gold can appear if it was embedded in stone and hero kicks it
1080 (on even via wish and drop) so don't assume hero has been warned */
1081 if (goldincorridor && !egrd->gddone) {
1082 gd_pick_corridor_gold(grd, m, n);
1083 if (!grd->mpeaceful)
1088 if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
1089 if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow
1090 && !(u.ustuck && !sticks(youmonst.data)))
1092 verbalize("Move along!");
1094 verbalize("
\97£
\82ê
\82é
\82È
\81I");
1096 return 0; /* didn't move */
1104 /* look around (hor & vert only) for accessible places */
1105 for (nx = x - 1; nx <= x + 1; nx++)
1106 for (ny = y - 1; ny <= y + 1; ny++) {
1107 if ((nx == x || ny == y) && (nx != x || ny != y)
1109 typ = (crm = &levl[nx][ny])->typ;
1110 if (!IS_STWALL(typ) && !IS_POOL(typ)) {
1111 if (in_fcorridor(grd, nx, ny))
1114 if (*in_rooms(nx, ny, VAULT))
1117 /* seems we found a good place to leave him alone */
1119 if (ACCESSIBLE(typ))
1127 crm->typ = (typ == SCORR) ? CORR : DOOR;
1129 if (crm->typ == DOOR)
1130 crm->doormask = D_NODOOR;
1142 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
1143 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
1144 if (abs(gx - x) >= abs(gy - y))
1149 while ((typ = (crm = &levl[nx][ny])->typ) != STONE) {
1150 /* in view of the above we must have IS_WALL(typ) or typ == POOL */
1151 /* must be a wall here */
1152 if (isok(nx + nx - x, ny + ny - y) && !IS_POOL(typ)
1153 && IS_ROOM(levl[nx + nx - x][ny + ny - y].typ)) {
1155 crm->doormask = D_NODOOR;
1158 if (dy && nx != x) {
1163 if (dx && ny != y) {
1169 /* I don't like this, but ... */
1172 crm->doormask = D_NODOOR;
1180 unblock_point(nx, ny); /* doesn't block light */
1184 if ((nx != gx || ny != gy) || (grd->mx != gx || grd->my != gy)) {
1185 fcp = &(egrd->fakecorr[egrd->fcend]);
1186 if (egrd->fcend++ == FCSIZ)
1187 panic("fakecorr overflow");
1191 } else if (!egrd->gddone) {
1192 /* We're stuck, so try to find a new destination. */
1193 if (!find_guard_dest(grd, &egrd->gdx, &egrd->gdy)
1194 || (egrd->gdx == gx && egrd->gdy == gy)) {
1195 pline("%s, confused, disappears.", Monnam(grd));
1196 disappear_msg_seen = TRUE;
1202 gd_mv_monaway(grd, nx, ny);
1204 /* The following is a kludge. We need to keep */
1205 /* the guard around in order to be able to make */
1206 /* the fake corridor disappear as the player */
1207 /* moves out of it, but we also need the guard */
1208 /* out of the way. We send the guard to never- */
1209 /* never land. We set ogx ogy to mx my in order */
1210 /* to avoid a check at the top of this function. */
1211 /* At the end of the process, the guard is killed */
1212 /* in restfakecorr(). */
1214 x = grd->mx, y = grd->my;
1215 see_guard = canspotmon(grd);
1216 parkguard(grd); /* move to <0,0> */
1219 debugpline2("gd_move: %scleanup%s",
1220 grd->isgd ? "" : "final ",
1221 grd->isgd ? " attempt" : "");
1222 if (!semi_dead && (in_fcorridor(grd, u.ux, u.uy) || cansee(x, y))) {
1223 if (!disappear_msg_seen && see_guard)
1225 pline("Suddenly, %s disappears.", noit_mon_nam(grd));
1227 pline("
\93Ë
\91R
\81C%s
\82Í
\8fÁ
\82¦
\82½
\81D", noit_mon_nam(grd));
1232 egrd->ogx = grd->mx; /* update old positions */
1233 egrd->ogy = grd->my;
1234 remove_monster(grd->mx, grd->my);
1235 place_monster(grd, nx, ny);
1236 if (newspot && g_at(nx, ny)) {
1237 /* if there's gold already here (most likely from mineralize()),
1238 pick it up now so that guard doesn't later think hero dropped
1239 it and give an inappropriate message */
1241 if (canspotmon(grd))
1243 pline("%s picks up some gold.", Monnam(grd));
1245 pline("%s
\82Í
\8bà
\82ð
\8fE
\82Á
\82½
\81D", Monnam(grd));
1247 newsym(grd->mx, grd->my);
1252 /* Routine when dying or quitting with a vault guard around */
1257 register struct monst *grd = findgd();
1258 long umoney = money_cnt(invent);
1259 struct obj *coins, *nextcoins;
1263 if (!umoney || !grd)
1269 Your("%ld %s goes into the Magic Memory Vault.",
1270 umoney, currency(umoney));
1272 Your("%ld%s
\82Í
\96\82\96@
\82Ì
\8bL
\94O
\91q
\8cÉ
\82É
\93ü
\82Á
\82½
\81D",
1273 umoney, currency(umoney));
1278 if (grd->mpeaceful) /* peaceful guard has no "right" to your gold */
1284 pline("%s remits your gold to the vault.", Monnam(grd));
1286 pline("%s
\82Í
\82 \82È
\82½
\82Ì
\8bà
\89Ý
\82ð
\91q
\8cÉ
\82É
\91\97\82Á
\82½
\81D", Monnam(grd));
1287 gx = rooms[EGD(grd)->vroom].lx + rn2(2);
1288 gy = rooms[EGD(grd)->vroom].ly + rn2(2);
1290 Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.",
1291 plname, mons[u.umonster].mname);
1293 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",
1294 mons[u.umonster].mname, plname);
1296 make_grave(gx, gy, buf);
1298 for (coins = invent; coins; coins = nextcoins) {
1299 nextcoins = coins->nobj;
1300 if (objects[coins->otyp].oc_class == COIN_CLASS) {
1302 place_object(coins, gx, gy);
1317 for (obj = invent; obj; obj = obj->nobj)
1318 if (Has_contents(obj))
1319 value += contained_gold(obj);
1320 /* unknown gold stuck inside statues may cause some consternation... */
1325 /* prevent "You hear footsteps.." when inappropriate */
1329 struct monst *grd = findgd();
1331 if (vault_occupied(u.urooms))
1334 return (boolean) (grd == (struct monst *) 0);
1338 vault_gd_watching(activity)
1339 unsigned int activity;
1341 struct monst *guard = findgd();
1343 if (guard && guard->mcansee && m_canseeu(guard)) {
1344 if (activity == GD_EATGOLD || activity == GD_DESTROYGOLD)
1345 EGD(guard)->witness = activity;