Blindfold removal fix
[slashemextended.git] / src / vault.c
blobb70cc24c6a570a75f281290448802ba01482199b
1 /* SCCS Id: @(#)vault.c 3.4 2003/01/15 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
6 #include "vault.h"
8 STATIC_DCL struct monst *findgd(void);
10 #define g_monnam(mtmp) \
11 x_monnam(mtmp, ARTICLE_NONE, (char *)0, SUPPRESS_IT, FALSE)
13 #ifdef OVLB
15 STATIC_DCL boolean clear_fcorr(struct monst *,BOOLEAN_P);
16 STATIC_DCL void restfakecorr(struct monst *);
17 STATIC_DCL boolean in_fcorridor(struct monst *,int,int);
18 STATIC_DCL void move_gold(struct obj *,int);
19 STATIC_DCL void wallify_vault(struct monst *);
21 STATIC_OVL boolean
22 clear_fcorr(grd, forceshow)
23 register struct monst *grd;
24 register boolean forceshow;
26 register int fcx, fcy, fcbeg;
27 register struct monst *mtmp;
29 if (!on_level(&(EGD(grd)->gdlevel), &u.uz)) return TRUE;
31 while((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
32 fcx = EGD(grd)->fakecorr[fcbeg].fx;
33 fcy = EGD(grd)->fakecorr[fcbeg].fy;
34 if((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
35 EGD(grd)->gddone)
36 forceshow = TRUE;
37 if((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
38 || (!forceshow && couldsee(fcx,fcy))
39 || (Punished && !carried(uball)
40 && uball->ox == fcx && uball->oy == fcy))
41 return FALSE;
43 if ((mtmp = m_at(fcx,fcy)) != 0) {
44 if(mtmp->isgd) return(FALSE);
45 else if(!in_fcorridor(grd, u.ux, u.uy)) {
46 if(mtmp->mtame) yelp(mtmp);
47 (void) rloc(mtmp, FALSE);
50 levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
51 map_location(fcx, fcy, 1); /* bypass vision */
52 if(!ACCESSIBLE(levl[fcx][fcy].typ)) block_point(fcx,fcy);
53 EGD(grd)->fcbeg++;
55 if(grd->mhp <= 0) {
56 pline_The("corridor disappears.");
57 if(IS_ROCK(levl[u.ux][u.uy].typ)) You("are encased in rock.");
59 return(TRUE);
62 STATIC_OVL void
63 restfakecorr(grd)
64 register struct monst *grd;
66 /* it seems you left the corridor - let the guard disappear */
67 if(clear_fcorr(grd, FALSE)) mongone(grd);
70 boolean
71 grddead(grd) /* called in mon.c */
72 register struct monst *grd;
74 register boolean dispose = clear_fcorr(grd, TRUE);
76 if(!dispose) {
77 /* see comment by newpos in gd_move() */
78 remove_monster(grd->mx, grd->my);
79 newsym(grd->mx, grd->my);
80 place_monster(grd, 0, 0);
81 EGD(grd)->ogx = grd->mx;
82 EGD(grd)->ogy = grd->my;
83 dispose = clear_fcorr(grd, TRUE);
85 return(dispose);
88 STATIC_OVL boolean
89 in_fcorridor(grd, x, y)
90 register struct monst *grd;
91 int x, y;
93 register int fci;
95 for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++)
96 if(x == EGD(grd)->fakecorr[fci].fx &&
97 y == EGD(grd)->fakecorr[fci].fy)
98 return(TRUE);
99 return(FALSE);
102 STATIC_OVL
103 struct monst *
104 findgd()
106 register struct monst *mtmp;
108 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
109 if(mtmp->isgd && !DEADMONSTER(mtmp) && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
110 return(mtmp);
111 return((struct monst *)0);
114 #endif /* OVLB */
115 #ifdef OVL0
117 char
118 vault_occupied(array)
119 char *array;
121 register char *ptr;
123 for (ptr = array; *ptr; ptr++)
124 if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
125 return(*ptr);
126 return('\0');
129 void
130 invault()
132 #ifdef BSD_43_BUG
133 int dummy; /* hack to avoid schain botch */
134 #endif
135 struct monst *guard;
136 int trycount, vaultroom = (int)vault_occupied(u.urooms);
138 if(!vaultroom) {
139 u.uinvault = 0;
140 return;
143 vaultroom -= ROOMOFFSET;
145 guard = findgd();
146 if(++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
147 char buf[BUFSZ];
148 register int x, y, dd, gx, gy;
149 int lx = 0, ly = 0;
150 #ifdef GOLDOBJ
151 long umoney;
152 #endif
153 /* first find the goal for the guard */
154 for(dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
155 for(y = u.uy-dd; y <= u.uy+dd; ly = y, y++) {
156 if(y < 0 || y > ROWNO-1) continue;
157 for(x = u.ux-dd; x <= u.ux+dd; lx = x, x++) {
158 if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
159 x = u.ux+dd;
160 if(x < 1 || x > COLNO-1) continue;
161 if(levl[x][y].typ == CORR) {
162 if(x < u.ux) lx = x + 1;
163 else if(x > u.ux) lx = x - 1;
164 else lx = x;
165 if(y < u.uy) ly = y + 1;
166 else if(y > u.uy) ly = y - 1;
167 else ly = y;
168 if(levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
169 goto incr_radius;
170 goto fnd;
174 incr_radius: ;
176 impossible("Not a single corridor on this level??");
177 tele();
178 return;
179 fnd:
180 gx = x; gy = y;
182 /* next find a good place for a door in the wall */
183 x = u.ux; y = u.uy;
184 if(levl[x][y].typ != ROOM) { /* player dug a door and is in it */
185 if(levl[x+1][y].typ == ROOM) x = x + 1;
186 else if(levl[x][y+1].typ == ROOM) y = y + 1;
187 else if(levl[x-1][y].typ == ROOM) x = x - 1;
188 else if(levl[x][y-1].typ == ROOM) y = y - 1;
189 else if(levl[x+1][y+1].typ == ROOM) {
190 x = x + 1;
191 y = y + 1;
192 } else if (levl[x-1][y-1].typ == ROOM) {
193 x = x - 1;
194 y = y - 1;
195 } else if (levl[x+1][y-1].typ == ROOM) {
196 x = x + 1;
197 y = y - 1;
198 } else if (levl[x-1][y+1].typ == ROOM) {
199 x = x - 1;
200 y = y + 1;
203 while(levl[x][y].typ == ROOM) {
204 register int dx,dy;
206 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
207 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
208 if(abs(gx-x) >= abs(gy-y))
209 x += dx;
210 else
211 y += dy;
213 if(x == u.ux && y == u.uy) {
214 if(levl[x+1][y].typ == HWALL || levl[x+1][y].typ == DOOR)
215 x = x + 1;
216 else if(levl[x-1][y].typ == HWALL || levl[x-1][y].typ == DOOR)
217 x = x - 1;
218 else if(levl[x][y+1].typ == VWALL || levl[x][y+1].typ == DOOR)
219 y = y + 1;
220 else if(levl[x][y-1].typ == VWALL || levl[x][y-1].typ == DOOR)
221 y = y - 1;
222 else return;
225 /* make something interesting happen */
226 if(!(guard = makemon( ((level_difficulty() + u.pompejipermanentrecord) > 79) ? &mons[PM_ELITE_GUARD] : ((level_difficulty() + u.pompejipermanentrecord) > 59) ? &mons[PM_EXCEPTIONAL_GUARD] : ((level_difficulty() + u.pompejipermanentrecord) > 39) ? &mons[PM_MASTER_GUARD] : ((level_difficulty() + u.pompejipermanentrecord) > 19) ? &mons[PM_EXPERIENCED_GUARD] : &mons[PM_GUARD], x, y, NO_MM_FLAGS))) return;
227 guard->isgd = 1;
228 guard->mpeaceful = 1;
229 set_malign(guard);
230 EGD(guard)->gddone = 0;
231 EGD(guard)->ogx = x;
232 EGD(guard)->ogy = y;
233 assign_level(&(EGD(guard)->gdlevel), &u.uz);
234 EGD(guard)->vroom = vaultroom;
235 EGD(guard)->warncnt = 0;
237 reset_faint(); /* if fainted - wake up */
238 if (canspotmon(guard))
239 pline("Suddenly one of the Vault's %s enters!",
240 makeplural(g_monnam(guard)));
241 else
242 pline("Someone else has entered the Vault.");
243 newsym(guard->mx,guard->my);
244 if (youmonst.m_ap_type == M_AP_OBJECT || u.uundetected) {
245 if (youmonst.m_ap_type == M_AP_OBJECT &&
246 youmonst.mappearance != GOLD_PIECE)
247 verbalize("Hey! Who left that %s in here?", mimic_obj_name(&youmonst));
248 /* You're mimicking some object or you're hidden. */
249 pline("Puzzled, %s turns around and leaves.", mhe(guard));
250 mongone(guard);
251 return;
254 /* janitors on duty get a free pass; since there is no janitor uniform, they always count as on duty :D --Amy */
255 if (Role_if(PM_JANITOR)) {
256 verbalize("Oh, you're the janitor, I see. Now go and make that vault floor sparkle!");
257 mongone(guard);
258 return;
261 if((Role_if(PM_CONVICT) || Role_if(PM_MURDERER) || Race_if(PM_ALBAE) || Race_if(PM_PLAYER_DYNAMO)) && !Upolyd) {
262 setmangry(guard);
263 verbalize("I saw your pic on the wanted poster!");
264 if (!MON_WEP(guard)) {
265 guard->weapon_check = NEED_HTH_WEAPON;
266 (void) mon_wield_item(guard);
268 return;
270 if (Strangled || is_silent(youmonst.data) || multi < 0) {
271 /* [we ought to record whether this this message has already
272 been given in order to vary it upon repeat visits, but
273 discarding the monster and its egd data renders that hard] */
274 verbalize("I'll be back when you're ready to speak to me!");
275 mongone(guard);
276 return;
279 stop_occupation(); /* if occupied, stop it *now* */
280 if (multi > 0) { nomul(0, 0, FALSE); unmul((char *)0); }
281 trycount = 5;
283 if (Role_if(PM_BUTT_LOVER) && rn2(3)) {
284 verbalize("Hello stranger, who are you?");
285 pline("Since you cannot lie, you tell your name to the vault guard.");
286 strncpy(buf, plname, sizeof(buf));
287 goto gaveidentity;
290 do {
291 getlin("\"Hello stranger, who are you?\" -", buf);
292 (void) mungspaces(buf);
293 } while (!letter(buf[0]) && --trycount > 0);
295 if (u.ualign.type == A_LAWFUL &&
296 /* ignore trailing text, in case player includes character's rank */
297 strncmpi(buf, plname, (int) strlen(plname)) != 0 && (!plalias[0] || strncmpi(buf, plalias, (int) strlen(plalias)) != 0) ) {
298 adjalign(-1); /* Liar! */
301 if (Role_if(PM_BUTT_LOVER) && (strncmpi(buf, plname, (int) strlen(plname)) != 0 && (!plalias[0] || strncmpi(buf, plalias, (int) strlen(plalias)) != 0)) ) {
302 You("accidentally drop your pack, and bend over to pick it up...");
303 verbalize("Liar! You really thought that'd work on me, punk?");
304 setmangry(guard);
305 return;
308 if (!rn2(10) || (strncmpi(buf, plname, (int) strlen(plname)) != 0 && (!plalias[0] || strncmpi(buf, plalias, (int) strlen(plalias)) != 0)) ) {
309 boolean rumoristrue = rn2(2);
310 verbalize("I don't believe you. We will have to do a quiz to verify your identity.");
311 verbalize("You will now tell me whether the following rumor is true or not!");
313 if (rumoristrue) outrumor(1, BY_OTHER, TRUE);
314 else outrumor(-1, BY_OTHER, TRUE);
316 if (yn("Now tell me if this rumor was true!") != 'y') { /* player said it's false */
318 if (rumoristrue) {
319 verbalize("Ah-ha, you obviously lied! You don't even know the simplest facts! Well here's another one: You will die now, intruder.");
320 setmangry(guard);
321 return;
322 } else {
323 verbalize("You're right, this rumor was false. Sorry that I assumed you were lying to me.");
326 } else { /* player said it's true */
327 if (rumoristrue) {
328 verbalize("Correct! I see you actually gave me your true identity.");
329 } else {
330 verbalize("Of course not! Are you really that stupid? Do you know what happens to unwanted intruders in this vault? They die, and so will you now.");
331 setmangry(guard);
332 return;
339 gaveidentity:
341 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
342 || !strcmpi(buf, "Creosote")
344 if (!mvitals[PM_CROESUS].died) {
345 verbalize("Oh, yes, of course. Sorry to have disturbed you.");
346 mongone(guard);
347 } else {
348 setmangry(guard);
349 verbalize("Back from the dead, are you? I'll remedy that!");
350 /* don't want guard to waste next turn wielding a weapon */
351 if (!MON_WEP(guard)) {
352 guard->weapon_check = NEED_HTH_WEAPON;
353 (void) mon_wield_item(guard);
356 return;
359 verbalize("I don't know you.");
360 #ifndef GOLDOBJ
361 if (!u.ugold && !hidden_gold())
362 verbalize("Please follow me.");
363 else {
364 if (!u.ugold)
365 verbalize("You have hidden gold.");
366 verbalize("Most likely all your gold was stolen from this vault.");
367 verbalize("Please drop that gold and follow me.");
369 #else
370 umoney = money_cnt(invent);
371 if (!umoney && !hidden_gold())
372 verbalize("Please follow me.");
373 else {
374 if (!umoney)
375 verbalize("You have hidden money.");
376 verbalize("Most likely all your money was stolen from this vault.");
377 verbalize("Please drop that money and follow me.");
379 #endif
380 EGD(guard)->gdx = gx;
381 EGD(guard)->gdy = gy;
382 EGD(guard)->fcbeg = 0;
383 EGD(guard)->fakecorr[0].fx = x;
384 EGD(guard)->fakecorr[0].fy = y;
385 if(IS_WALL(levl[x][y].typ))
386 EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
387 else { /* the initial guard location is a dug door */
388 int vlt = EGD(guard)->vroom;
389 xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
390 xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
392 if(x == lowx-1 && y == lowy-1)
393 EGD(guard)->fakecorr[0].ftyp = TLCORNER;
394 else if(x == hix+1 && y == lowy-1)
395 EGD(guard)->fakecorr[0].ftyp = TRCORNER;
396 else if(x == lowx-1 && y == hiy+1)
397 EGD(guard)->fakecorr[0].ftyp = BLCORNER;
398 else if(x == hix+1 && y == hiy+1)
399 EGD(guard)->fakecorr[0].ftyp = BRCORNER;
400 else if(y == lowy-1 || y == hiy+1)
401 EGD(guard)->fakecorr[0].ftyp = HWALL;
402 else if(x == lowx-1 || x == hix+1)
403 EGD(guard)->fakecorr[0].ftyp = VWALL;
405 levl[x][y].typ = DOOR;
406 levl[x][y].doormask = D_NODOOR;
407 unblock_point(x, y); /* doesn't block light */
408 EGD(guard)->fcend = 1;
409 EGD(guard)->warncnt = 1;
413 #endif /* OVL0 */
414 #ifdef OVLB
416 STATIC_OVL void
417 move_gold(gold, vroom)
418 struct obj *gold;
419 int vroom;
421 xchar nx, ny;
423 remove_object(gold);
424 newsym(gold->ox, gold->oy);
425 nx = rooms[vroom].lx + rn2(2);
426 ny = rooms[vroom].ly + rn2(2);
427 place_object(gold, nx, ny);
428 stackobj(gold);
429 newsym(nx,ny);
432 STATIC_OVL void
433 wallify_vault(grd)
434 struct monst *grd;
436 int x, y, typ;
437 int vlt = EGD(grd)->vroom;
438 char tmp_viz;
439 xchar lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1,
440 loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1;
441 struct monst *mon;
442 struct obj *gold;
443 struct trap *trap;
444 boolean fixed = FALSE;
445 boolean movedgold = FALSE;
447 for (x = lox; x <= hix; x++)
448 for (y = loy; y <= hiy; y++) {
449 /* if not on the room boundary, skip ahead */
450 if (x != lox && x != hix && y != loy && y != hiy) continue;
452 if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
453 if ((mon = m_at(x, y)) != 0 && mon != grd) {
454 if (mon->mtame) yelp(mon);
455 (void) rloc(mon, FALSE);
457 if ((gold = g_at(x, y)) != 0) {
458 move_gold(gold, EGD(grd)->vroom);
459 movedgold = TRUE;
461 if ((trap = t_at(x, y)) != 0)
462 deltrap(trap);
463 if (x == lox)
464 typ = (y == loy) ? TLCORNER :
465 (y == hiy) ? BLCORNER : VWALL;
466 else if (x == hix)
467 typ = (y == loy) ? TRCORNER :
468 (y == hiy) ? BRCORNER : VWALL;
469 else /* not left or right side, must be top or bottom */
470 typ = HWALL;
471 levl[x][y].typ = typ;
472 levl[x][y].doormask = 0;
474 * hack: player knows walls are restored because of the
475 * message, below, so show this on the screen.
477 tmp_viz = viz_array[y][x];
478 viz_array[y][x] = IN_SIGHT|COULD_SEE;
479 newsym(x,y);
480 viz_array[y][x] = tmp_viz;
481 block_point(x,y);
482 fixed = TRUE;
486 if(movedgold || fixed) {
487 if(in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
488 pline_The("%s whispers an incantation.", g_monnam(grd));
489 else You_hear("a distant chant.");
490 if(movedgold)
491 pline("A mysterious force moves the gold into the vault.");
492 if(fixed)
493 pline_The("damaged vault's walls are magically restored!");
498 * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died
501 gd_move(grd)
502 register struct monst *grd;
504 int x, y, nx, ny, m, n;
505 int dx, dy, gx, gy, fci;
506 int copcnt;
507 uchar typ;
508 struct fakecorridor *fcp;
509 register struct egd *egrd = EGD(grd);
510 register struct rm *crm;
511 register boolean goldincorridor = FALSE,
512 u_in_vault = vault_occupied(u.urooms)? TRUE : FALSE,
513 grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT)?
514 TRUE : FALSE;
515 boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
516 #ifndef GOLDOBJ
517 register boolean u_carry_gold = ((u.ugold + hidden_gold()) > 0L);
518 #else
519 long umoney = money_cnt(invent);
520 register boolean u_carry_gold = ((umoney + hidden_gold()) > 0L);
521 #endif
522 boolean see_guard;
524 if(!on_level(&(egrd->gdlevel), &u.uz)) return(-1);
525 nx = ny = m = n = 0;
526 if(!u_in_vault && !grd_in_vault)
527 wallify_vault(grd);
528 if(!grd->mpeaceful) {
529 if(semi_dead) {
530 egrd->gddone =1;
531 goto newpos;
533 if(!u_in_vault &&
534 (grd_in_vault ||
535 (in_fcorridor(grd, grd->mx, grd->my) &&
536 !in_fcorridor(grd, u.ux, u.uy)))) {
537 (void) rloc(grd, FALSE);
538 wallify_vault(grd);
539 (void) clear_fcorr(grd, TRUE);
540 goto letknow;
542 if(!in_fcorridor(grd, grd->mx, grd->my))
543 (void) clear_fcorr(grd, TRUE);
544 return(-1);
546 if(abs(egrd->ogx - grd->mx) > 1 ||
547 abs(egrd->ogy - grd->my) > 1)
548 return(-1); /* teleported guard - treat as monster */
549 if(egrd->fcend == 1) {
550 if(u_in_vault &&
551 (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
552 if(egrd->warncnt == 3)
553 verbalize("I repeat, %sfollow me!",
554 u_carry_gold ? (
555 #ifndef GOLDOBJ
556 !u.ugold ?
557 "drop that hidden gold and " :
558 "drop that gold and ") : "");
559 #else
560 !umoney ?
561 "drop that hidden money and " :
562 "drop that money and ") : "");
563 #endif
564 if(egrd->warncnt == 7) {
565 m = grd->mx;
566 n = grd->my;
567 verbalize("You've been warned, knave!");
568 mnexto(grd);
569 levl[m][n].typ = egrd->fakecorr[0].ftyp;
570 newsym(m,n);
571 grd->mpeaceful = 0;
572 return(-1);
574 /* not fair to get mad when (s)he's fainted or paralyzed */
575 if(!is_fainted() && multi >= 0) egrd->warncnt++;
576 return(0);
579 if (!u_in_vault) {
580 if (u_carry_gold) { /* player teleported */
581 m = grd->mx;
582 n = grd->my;
583 (void) rloc(grd, FALSE);
584 levl[m][n].typ = egrd->fakecorr[0].ftyp;
585 newsym(m,n);
586 grd->mpeaceful = 0;
587 letknow:
588 if (!cansee(grd->mx, grd->my) || !mon_visible(grd))
589 You_hear("the shrill sound of a guard's whistle.");
590 else
591 You(um_dist(grd->mx, grd->my, 2) ?
592 "see an angry %s approaching." :
593 "are confronted by an angry %s.",
594 g_monnam(grd));
596 u.cnd_kopsummonamount++;
597 copcnt = rnd(monster_difficulty() ) + 1;
598 if (rn2(5)) copcnt = (copcnt / (rnd(4) + 1)) + 1;
599 if (Role_if(PM_CAMPERSTRIKER)) copcnt *= (rn2(5) ? 2 : rn2(5) ? 3 : 5);
601 if (uarmh && itemhasappearance(uarmh, APP_ANTI_GOVERNMENT_HELMET) ) {
602 copcnt = (copcnt / 2) + 1;
605 if (RngeAntiGovernment) {
606 copcnt = (copcnt / 2) + 1;
609 while(--copcnt >= 0) {
610 (void) makemon(mkclass(S_KOP,0), grd->mx, grd->my, MM_ANGRY|MM_ADJACENTOK|MM_FRENZIED);
612 if (!rn2(100)) {
614 int koptryct = 0;
615 int kox, koy;
617 for (koptryct = 0; koptryct < 2000; koptryct++) {
618 kox = rn1(COLNO-3,2);
619 koy = rn2(ROWNO);
621 if (kox && koy && isok(kox, koy) && (levl[kox][koy].typ > DBWALL) && !(t_at(kox, koy)) ) {
622 (void) maketrap(kox, koy, KOP_CUBE, 0, FALSE);
623 break;
629 } /* while */
631 return(-1);
632 } else {
633 verbalize("Well, begone.");
634 wallify_vault(grd);
635 egrd->gddone = 1;
636 goto cleanup;
641 if(egrd->fcend > 1) {
642 if(egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
643 !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
644 levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
645 == egrd->fakecorr[0].ftyp) {
646 pline_The("%s, confused, disappears.", g_monnam(grd));
647 disappear_msg_seen = TRUE;
648 goto cleanup;
650 if(u_carry_gold &&
651 (in_fcorridor(grd, u.ux, u.uy) ||
652 /* cover a 'blind' spot */
653 (egrd->fcend > 1 && u_in_vault))) {
654 if(!grd->mx) {
655 restfakecorr(grd);
656 return(-2);
658 if(egrd->warncnt < 6) {
659 egrd->warncnt = 6;
660 verbalize("Drop all your gold, scoundrel!");
661 return(0);
662 } else {
663 verbalize("So be it, rogue!");
664 grd->mpeaceful = 0;
665 return(-1);
669 for(fci = egrd->fcbeg; fci < egrd->fcend; fci++)
670 if(g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)){
671 m = egrd->fakecorr[fci].fx;
672 n = egrd->fakecorr[fci].fy;
673 goldincorridor = TRUE;
675 if(goldincorridor && !egrd->gddone) {
676 x = grd->mx;
677 y = grd->my;
678 if (m == u.ux && n == u.uy) {
679 struct obj *gold = g_at(m,n);
680 /* Grab the gold from between the hero's feet. */
681 #ifndef GOLDOBJ
682 grd->mgold += gold->quan;
683 delobj(gold);
684 #else
685 obj_extract_self(gold);
686 add_to_minv(grd, gold);
687 #endif
688 newsym(m,n);
689 } else if (m == x && n == y) {
690 mpickgold(grd); /* does a newsym */
691 } else {
692 /* just for insurance... */
693 if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
694 verbalize("Out of my way, scum!");
695 (void) rloc(m_at(m, n), FALSE);
697 remove_monster(grd->mx, grd->my);
698 newsym(grd->mx, grd->my);
699 place_monster(grd, m, n);
700 mpickgold(grd); /* does a newsym */
702 if(cansee(m,n))
703 pline("%s%s picks up the gold.", Monnam(grd),
704 grd->mpeaceful ? " calms down and" : "");
705 if(x != grd->mx || y != grd->my) {
706 remove_monster(grd->mx, grd->my);
707 newsym(grd->mx, grd->my);
708 place_monster(grd, x, y);
709 newsym(x, y);
711 if(!grd->mpeaceful) return(-1);
712 else {
713 egrd->warncnt = 5;
714 return(0);
717 if(um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
718 if(!egrd->gddone && !rn2(10)) verbalize("Move along!");
719 restfakecorr(grd);
720 return(0); /* didn't move */
722 x = grd->mx;
723 y = grd->my;
725 if(u_in_vault) goto nextpos;
727 /* look around (hor & vert only) for accessible places */
728 for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
729 if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {
731 typ = (crm = &levl[nx][ny])->typ;
732 if(!IS_STWALL(typ) && !IS_POOL(typ)) {
734 if(in_fcorridor(grd, nx, ny))
735 goto nextnxy;
737 if(*in_rooms(nx,ny,VAULT))
738 continue;
740 /* seems we found a good place to leave him alone */
741 egrd->gddone = 1;
742 if(ACCESSIBLE(typ)) goto newpos;
743 #ifdef STUPID
744 if (typ == SCORR)
745 crm->typ = CORR;
746 else
747 crm->typ = DOOR;
748 #else
749 crm->typ = (typ == SCORR) ? CORR : DOOR;
750 #endif
751 if(crm->typ == DOOR) crm->doormask = D_NODOOR;
752 goto proceed;
755 nextnxy: ;
757 nextpos:
758 nx = x;
759 ny = y;
760 gx = egrd->gdx;
761 gy = egrd->gdy;
762 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
763 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
764 if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
766 while((typ = (crm = &levl[nx][ny])->typ) != 0) {
767 /* in view of the above we must have IS_WALL(typ) or typ == POOL */
768 /* must be a wall here */
769 if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) &&
770 IS_ROOM(levl[nx+nx-x][ny+ny-y].typ)){
771 crm->typ = DOOR;
772 crm->doormask = D_NODOOR;
773 goto proceed;
775 if(dy && nx != x) {
776 nx = x; ny = y+dy;
777 continue;
779 if(dx && ny != y) {
780 ny = y; nx = x+dx; dy = 0;
781 continue;
783 /* I don't like this, but ... */
784 if(IS_ROOM(typ)) {
785 crm->typ = DOOR;
786 crm->doormask = D_NODOOR;
787 goto proceed;
789 break;
791 crm->typ = CORR;
792 proceed:
793 unblock_point(nx, ny); /* doesn't block light */
794 if (cansee(nx,ny))
795 newsym(nx,ny);
797 fcp = &(egrd->fakecorr[egrd->fcend]);
798 if(egrd->fcend++ == FCSIZ) panic("fakecorr overflow");
799 fcp->fx = nx;
800 fcp->fy = ny;
801 fcp->ftyp = typ;
802 newpos:
803 if(egrd->gddone) {
804 /* The following is a kludge. We need to keep */
805 /* the guard around in order to be able to make */
806 /* the fake corridor disappear as the player */
807 /* moves out of it, but we also need the guard */
808 /* out of the way. We send the guard to never- */
809 /* never land. We set ogx ogy to mx my in order */
810 /* to avoid a check at the top of this function. */
811 /* At the end of the process, the guard is killed */
812 /* in restfakecorr(). */
813 cleanup:
814 x = grd->mx; y = grd->my;
816 see_guard = canspotmon(grd);
817 wallify_vault(grd);
818 remove_monster(grd->mx, grd->my);
819 newsym(grd->mx,grd->my);
820 place_monster(grd, 0, 0);
821 egrd->ogx = grd->mx;
822 egrd->ogy = grd->my;
823 restfakecorr(grd);
824 if(!semi_dead && (in_fcorridor(grd, u.ux, u.uy) ||
825 cansee(x, y))) {
826 if (!disappear_msg_seen && see_guard)
827 pline("Suddenly, the %s disappears.", g_monnam(grd));
828 return(1);
830 return(-2);
832 egrd->ogx = grd->mx; /* update old positions */
833 egrd->ogy = grd->my;
834 remove_monster(grd->mx, grd->my);
835 place_monster(grd, nx, ny);
836 newsym(grd->mx,grd->my);
837 restfakecorr(grd);
838 return(1);
841 /* Routine when dying or quitting with a vault guard around */
842 void
843 paygd()
845 register struct monst *grd = findgd();
846 #ifndef GOLDOBJ
847 struct obj *gold;
848 #else
849 long umoney = money_cnt(invent);
850 struct obj *coins, *nextcoins;
851 #endif
852 int gx,gy;
853 char buf[BUFSZ];
855 #ifndef GOLDOBJ
856 if (!u.ugold || !grd) return;
857 #else
858 if (!umoney || !grd) return;
859 #endif
861 if (u.uinvault) {
862 Your("%ld %s goes into the Magic Memory Vault.",
863 #ifndef GOLDOBJ
864 u.ugold,
865 currency(u.ugold));
866 #else
867 umoney,
868 currency(umoney));
869 #endif
870 gx = u.ux;
871 gy = u.uy;
872 } else {
873 if(grd->mpeaceful) { /* guard has no "right" to your gold */
874 mongone(grd);
875 return;
877 mnexto(grd);
878 pline("%s remits your gold to the vault.", Monnam(grd));
879 gx = rooms[EGD(grd)->vroom].lx + rn2(2);
880 gy = rooms[EGD(grd)->vroom].ly + rn2(2);
881 sprintf(buf,
882 "To Croesus: here's the gold recovered from %s the %s.",
883 playeraliasname, mons[u.umonster].mname);
884 make_grave(gx, gy, buf);
886 #ifndef GOLDOBJ
887 place_object(gold = mkgoldobj(u.ugold), gx, gy);
888 stackobj(gold);
889 #else
890 for (coins = invent; coins; coins = nextcoins) {
891 nextcoins = coins->nobj;
892 if (objects[coins->otyp].oc_class == COIN_CLASS) {
893 freeinv(coins);
894 place_object(coins, gx, gy);
895 stackobj(coins);
898 #endif
899 mongone(grd);
902 long
903 hidden_gold()
905 register long value = 0L;
906 register struct obj *obj;
908 for (obj = invent; obj; obj = obj->nobj)
909 if (Has_contents(obj))
910 value += contained_gold(obj);
911 /* unknown gold stuck inside statues may cause some consternation... */
913 return(value);
916 boolean
917 gd_sound() /* prevent "You hear footsteps.." when inappropriate */
919 register struct monst *grd = findgd();
921 if (vault_occupied(u.urooms)) return(FALSE);
922 else return((boolean)(grd == (struct monst *)0));
925 #endif /* OVLB */
927 /*vault.c*/