1 /* SCCS Id: @(#)vault.c 3.3 96/06/05 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 #include "hack.h"
6 #include "vault.h"
7
8 STATIC_DCL struct monst *NDECL(findgd);
9
10 #ifdef OVLB
11
12 STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *,BOOLEAN_P));
13 STATIC_DCL void FDECL(restfakecorr,(struct monst *));
14 STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *,int,int));
15 STATIC_DCL void FDECL(move_gold,(struct obj *,int));
16 STATIC_DCL void FDECL(wallify_vault,(struct monst *));
17
18 STATIC_OVL boolean
clear_fcorr(grd,forceshow)19 clear_fcorr(grd, forceshow)
20 register struct monst *grd;
21 register boolean forceshow;
22 {
23 register int fcx, fcy, fcbeg;
24 register struct monst *mtmp;
25
26 while((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
27 fcx = EGD(grd)->fakecorr[fcbeg].fx;
28 fcy = EGD(grd)->fakecorr[fcbeg].fy;
29 if((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
30 EGD(grd)->gddone)
31 forceshow = TRUE;
32 if((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
33 || (!forceshow && couldsee(fcx,fcy))
34 || (Punished && !carried(uball)
35 && uball->ox == fcx && uball->oy == fcy))
36 return FALSE;
37
38 if ((mtmp = m_at(fcx,fcy)) != 0) {
39 if(mtmp->isgd) return(FALSE);
40 else if(!in_fcorridor(grd, u.ux, u.uy)) {
41 if(mtmp->mtame) yelp(mtmp);
42 rloc(mtmp);
43 }
44 }
45 levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
46 map_location(fcx, fcy, 1); /* bypass vision */
47 if(!ACCESSIBLE(levl[fcx][fcy].typ)) block_point(fcx,fcy);
48 EGD(grd)->fcbeg++;
49 }
50 if(grd->mhp <= 0) {
51 pline_The("corridor disappears.");
52 if(IS_ROCK(levl[u.ux][u.uy].typ)) You("are encased in rock.");
53 }
54 return(TRUE);
55 }
56
57 STATIC_OVL void
restfakecorr(grd)58 restfakecorr(grd)
59 register struct monst *grd;
60 {
61 /* it seems you left the corridor - let the guard disappear */
62 if(clear_fcorr(grd, FALSE)) mongone(grd);
63 }
64
65 boolean
grddead(grd)66 grddead(grd) /* called in mon.c */
67 register struct monst *grd;
68 {
69 register boolean dispose = clear_fcorr(grd, TRUE);
70
71 if(!dispose) {
72 /* see comment by newpos in gd_move() */
73 remove_monster(grd->mx, grd->my);
74 newsym(grd->mx, grd->my);
75 place_monster(grd, 0, 0);
76 EGD(grd)->ogx = grd->mx;
77 EGD(grd)->ogy = grd->my;
78 dispose = clear_fcorr(grd, TRUE);
79 }
80 return(dispose);
81 }
82
83 STATIC_OVL boolean
in_fcorridor(grd,x,y)84 in_fcorridor(grd, x, y)
85 register struct monst *grd;
86 int x, y;
87 {
88 register int fci;
89
90 for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++)
91 if(x == EGD(grd)->fakecorr[fci].fx &&
92 y == EGD(grd)->fakecorr[fci].fy)
93 return(TRUE);
94 return(FALSE);
95 }
96
97 STATIC_OVL
98 struct monst *
findgd()99 findgd()
100 {
101 register struct monst *mtmp;
102
103 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
104 if(mtmp->isgd && !DEADMONSTER(mtmp) && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
105 return(mtmp);
106 return((struct monst *)0);
107 }
108
109 #endif /* OVLB */
110 #ifdef OVL0
111
112 char
vault_occupied(array)113 vault_occupied(array)
114 char *array;
115 {
116 register char *ptr;
117
118 for (ptr = array; *ptr; ptr++)
119 if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
120 return(*ptr);
121 return('\0');
122 }
123
124 void
invault()125 invault()
126 {
127 #ifdef BSD_43_BUG
128 int dummy; /* hack to avoid schain botch */
129 #endif
130 struct monst *guard;
131 int vaultroom = (int)vault_occupied(u.urooms);
132
133 if(!vaultroom) {
134 u.uinvault = 0;
135 return;
136 }
137
138 vaultroom -= ROOMOFFSET;
139
140 guard = findgd();
141 if(++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
142 char buf[BUFSZ];
143 register int x, y, dd, gx, gy;
144 int lx = 0, ly = 0;
145
146 /* first find the goal for the guard */
147 for(dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
148 for(y = u.uy-dd; y <= u.uy+dd; ly = y, y++) {
149 if(y < 0 || y > ROWNO-1) continue;
150 for(x = u.ux-dd; x <= u.ux+dd; lx = x, x++) {
151 if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
152 x = u.ux+dd;
153 if(x < 1 || x > COLNO-1) continue;
154 if(levl[x][y].typ == CORR) {
155 if(x < u.ux) lx = x + 1;
156 else if(x > u.ux) lx = x - 1;
157 else lx = x;
158 if(y < u.uy) ly = y + 1;
159 else if(y > u.uy) ly = y - 1;
160 else ly = y;
161 if(levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
162 goto incr_radius;
163 goto fnd;
164 }
165 }
166 }
167 incr_radius: ;
168 }
169 impossible("Not a single corridor on this level??");
170 tele();
171 return;
172 fnd:
173 gx = x; gy = y;
174
175 /* next find a good place for a door in the wall */
176 x = u.ux; y = u.uy;
177 if(levl[x][y].typ != ROOM) { /* player dug a door and is in it */
178 if(levl[x+1][y].typ == ROOM) x = x + 1;
179 else if(levl[x][y+1].typ == ROOM) y = y + 1;
180 else if(levl[x-1][y].typ == ROOM) x = x - 1;
181 else if(levl[x][y-1].typ == ROOM) y = y - 1;
182 else if(levl[x+1][y+1].typ == ROOM) {
183 x = x + 1;
184 y = y + 1;
185 } else if (levl[x-1][y-1].typ == ROOM) {
186 x = x - 1;
187 y = y - 1;
188 } else if (levl[x+1][y-1].typ == ROOM) {
189 x = x + 1;
190 y = y - 1;
191 } else if (levl[x-1][y+1].typ == ROOM) {
192 x = x - 1;
193 y = y + 1;
194 }
195 }
196 while(levl[x][y].typ == ROOM) {
197 register int dx,dy;
198
199 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
200 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
201 if(abs(gx-x) >= abs(gy-y))
202 x += dx;
203 else
204 y += dy;
205 }
206 if(x == u.ux && y == u.uy) {
207 if(levl[x+1][y].typ == HWALL || levl[x+1][y].typ == DOOR)
208 x = x + 1;
209 else if(levl[x-1][y].typ == HWALL || levl[x-1][y].typ == DOOR)
210 x = x - 1;
211 else if(levl[x][y+1].typ == VWALL || levl[x][y+1].typ == DOOR)
212 y = y + 1;
213 else if(levl[x][y-1].typ == VWALL || levl[x][y-1].typ == DOOR)
214 y = y - 1;
215 else return;
216 }
217
218 /* make something interesting happen */
219 if(!(guard = makemon(&mons[PM_GUARD], x, y, NO_MM_FLAGS))) return;
220 guard->isgd = 1;
221 guard->mpeaceful = 1;
222 set_malign(guard);
223 EGD(guard)->gddone = 0;
224 EGD(guard)->ogx = x;
225 EGD(guard)->ogy = y;
226 assign_level(&(EGD(guard)->gdlevel), &u.uz);
227 EGD(guard)->vroom = vaultroom;
228 EGD(guard)->warncnt = 0;
229
230 if(!cansee(guard->mx, guard->my)) {
231 mongone(guard);
232 return;
233 }
234
235 reset_faint(); /* if fainted - wake up */
236 pline("Suddenly one of the Vault's guards enters!");
237 newsym(guard->mx,guard->my);
238 if (Strangled || youmonst.data->msound == MS_SILENT) {
239 verbalize("I'll be back when you're ready to speak to me!");
240 mongone(guard);
241 return;
242 }
243 stop_occupation(); /* if occupied, stop it *now* */
244 do {
245 getlin("\"Hello stranger, who are you?\" -",buf);
246 } while (!letter(buf[0]));
247
248 if (u.ualign.type == A_LAWFUL &&
249 /* ignore trailing text, in case player includes character's rank */
250 strncmpi(buf, plname, (int) strlen(plname)) != 0) {
251 adjalign(-1); /* Liar! */
252 }
253
254 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos")
255 #ifdef TOURIST
256 || !strcmpi(buf, "Creosote")
257 #endif
258 ) {
259 if (!mvitals[PM_CROESUS].died) {
260 verbalize("Oh, yes, of course. Sorry to have disturbed you.");
261 mongone(guard);
262 } else {
263 setmangry(guard);
264 verbalize("Back from the dead, are you? I'll remedy that!");
265 /* don't want guard to waste next turn wielding a weapon */
266 if (!MON_WEP(guard)) {
267 guard->weapon_check = NEED_HTH_WEAPON;
268 (void) mon_wield_item(guard);
269 }
270 }
271 return;
272 }
273 verbalize("I don't know you.");
274 if (!u.ugold && !hidden_gold())
275 verbalize("Please follow me.");
276 else {
277 if (!u.ugold)
278 verbalize("You have hidden gold.");
279 verbalize("Most likely all your gold was stolen from this vault.");
280 verbalize("Please drop that gold and follow me.");
281 }
282 EGD(guard)->gdx = gx;
283 EGD(guard)->gdy = gy;
284 EGD(guard)->fcbeg = 0;
285 EGD(guard)->fakecorr[0].fx = x;
286 EGD(guard)->fakecorr[0].fy = y;
287 if(IS_WALL(levl[x][y].typ))
288 EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
289 else { /* the initial guard location is a dug door */
290 int vlt = EGD(guard)->vroom;
291 xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
292 xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
293
294 if(x == lowx-1 && y == lowy-1)
295 EGD(guard)->fakecorr[0].ftyp = TLCORNER;
296 else if(x == hix+1 && y == lowy-1)
297 EGD(guard)->fakecorr[0].ftyp = TRCORNER;
298 else if(x == lowx-1 && y == hiy+1)
299 EGD(guard)->fakecorr[0].ftyp = BLCORNER;
300 else if(x == hix+1 && y == hiy+1)
301 EGD(guard)->fakecorr[0].ftyp = BRCORNER;
302 else if(y == lowy-1 || y == hiy+1)
303 EGD(guard)->fakecorr[0].ftyp = HWALL;
304 else if(x == lowx-1 || x == hix+1)
305 EGD(guard)->fakecorr[0].ftyp = VWALL;
306 }
307 levl[x][y].typ = DOOR;
308 levl[x][y].doormask = D_NODOOR;
309 unblock_point(x, y); /* doesn't block light */
310 EGD(guard)->fcend = 1;
311 EGD(guard)->warncnt = 1;
312 }
313 }
314
315 #endif /* OVL0 */
316 #ifdef OVLB
317
318 STATIC_OVL void
move_gold(gold,vroom)319 move_gold(gold, vroom)
320 struct obj *gold;
321 int vroom;
322 {
323 xchar nx, ny;
324
325 remove_object(gold);
326 newsym(gold->ox, gold->oy);
327 nx = rooms[vroom].lx + rn2(2);
328 ny = rooms[vroom].ly + rn2(2);
329 place_object(gold, nx, ny);
330 stackobj(gold);
331 newsym(nx,ny);
332 }
333
334 STATIC_OVL void
wallify_vault(grd)335 wallify_vault(grd)
336 struct monst *grd;
337 {
338 int x, y;
339 int vlt = EGD(grd)->vroom;
340 char tmp_viz;
341 xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
342 xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
343 register struct obj *gold;
344 register boolean fixed = FALSE;
345 register boolean movedgold = FALSE;
346
347 for(x = lowx-1; x <= hix+1; x++)
348 for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
349 if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
350 if(MON_AT(x, y) && grd->mx != x && grd->my != y) {
351 struct monst *mon = m_at(x,y);
352 if (mon->mtame) yelp(mon);
353 rloc(mon);
354 }
355 if ((gold = g_at(x, y)) != 0) {
356 move_gold(gold, EGD(grd)->vroom);
357 movedgold = TRUE;
358 }
359 if(x == lowx-1 && y == lowy-1)
360 levl[x][y].typ = TLCORNER;
361 else if(x == hix+1 && y == lowy-1)
362 levl[x][y].typ = TRCORNER;
363 else if(x == lowx-1 && y == hiy+1)
364 levl[x][y].typ = BLCORNER;
365 else if(x == hix+1 && y == hiy+1)
366 levl[x][y].typ = BRCORNER;
367 else levl[x][y].typ = HWALL;
368
369 levl[x][y].doormask = 0;
370 /*
371 * hack: player knows walls are restored because of the
372 * message, below, so show this on the screen.
373 */
374 tmp_viz = viz_array[y][x];
375 viz_array[y][x] = IN_SIGHT|COULD_SEE;
376 newsym(x,y);
377 viz_array[y][x] = tmp_viz;
378 block_point(x,y);
379 fixed = TRUE;
380 }
381 }
382 for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
383 for(y = lowy; y <= hiy; y++) {
384 if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
385 if(MON_AT(x, y) && grd->mx != x && grd->my != y) {
386 struct monst *mon = m_at(x,y);
387 if (mon->mtame) yelp(mon);
388 rloc(mon);
389 }
390 if ((gold = g_at(x, y)) != 0) {
391 move_gold(gold, EGD(grd)->vroom);
392 movedgold = TRUE;
393 }
394 levl[x][y].typ = VWALL;
395 levl[x][y].doormask = 0;
396 tmp_viz = viz_array[y][x];
397 viz_array[y][x] = IN_SIGHT|COULD_SEE;
398 newsym(x,y);
399 viz_array[y][x] = tmp_viz;
400 block_point(x,y);
401 fixed = TRUE;
402 }
403 }
404
405 if(movedgold || fixed) {
406 if(in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
407 pline_The("guard whispers an incantation.");
408 else You_hear("a distant chant.");
409 if(movedgold)
410 pline("A mysterious force moves the gold into the vault.");
411 if(fixed)
412 pline_The("damaged vault's walls are magically restored!");
413 }
414 }
415
416 /*
417 * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died
418 */
419 int
gd_move(grd)420 gd_move(grd)
421 register struct monst *grd;
422 {
423 int x, y, nx, ny, m, n;
424 int dx, dy, gx, gy, fci;
425 uchar typ;
426 struct fakecorridor *fcp;
427 register struct egd *egrd = EGD(grd);
428 register struct rm *crm;
429 register boolean goldincorridor = FALSE,
430 u_in_vault = vault_occupied(u.urooms)? TRUE : FALSE,
431 grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT)?
432 TRUE : FALSE;
433 boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
434 register boolean u_carry_gold = ((u.ugold + hidden_gold()) > 0L);
435
436 if(!on_level(&(egrd->gdlevel), &u.uz)) return(-1);
437 nx = ny = m = n = 0;
438 if(!u_in_vault && !grd_in_vault)
439 wallify_vault(grd);
440 if(!grd->mpeaceful) {
441 if(semi_dead) {
442 egrd->gddone =1;
443 goto newpos;
444 }
445 if(!u_in_vault &&
446 (grd_in_vault ||
447 (in_fcorridor(grd, grd->mx, grd->my) &&
448 !in_fcorridor(grd, u.ux, u.uy)))) {
449 rloc(grd);
450 wallify_vault(grd);
451 (void) clear_fcorr(grd, TRUE);
452 goto letknow;
453 }
454 if(!in_fcorridor(grd, grd->mx, grd->my))
455 (void) clear_fcorr(grd, TRUE);
456 return(-1);
457 }
458 if(abs(egrd->ogx - grd->mx) > 1 ||
459 abs(egrd->ogy - grd->my) > 1)
460 return(-1); /* teleported guard - treat as monster */
461 if(egrd->fcend == 1) {
462 if(u_in_vault &&
463 (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
464 if(egrd->warncnt == 3)
465 verbalize("I repeat, %sfollow me!",
466 u_carry_gold ? (!u.ugold ?
467 "drop that hidden gold and " :
468 "drop that gold and ") : "");
469 if(egrd->warncnt == 7) {
470 m = grd->mx;
471 n = grd->my;
472 verbalize("You've been warned, knave!");
473 mnexto(grd);
474 levl[m][n].typ = egrd->fakecorr[0].ftyp;
475 newsym(m,n);
476 grd->mpeaceful = 0;
477 return(-1);
478 }
479 /* not fair to get mad when (s)he's fainted or paralyzed */
480 if(!is_fainted() && multi >= 0) egrd->warncnt++;
481 return(0);
482 }
483
484 if (!u_in_vault) {
485 if (u_carry_gold) { /* player teleported */
486 m = grd->mx;
487 n = grd->my;
488 rloc(grd);
489 levl[m][n].typ = egrd->fakecorr[0].ftyp;
490 newsym(m,n);
491 grd->mpeaceful = 0;
492 letknow:
493 if(!cansee(grd->mx, grd->my))
494 You_hear("the shrill sound of a guard's whistle.");
495 else
496 You(um_dist(grd->mx, grd->my, 2) ?
497 "see an angry %s approaching." :
498 "are confronted by an angry %s.",
499 l_monnam(grd));
500 return(-1);
501 } else {
502 verbalize("Well, begone.");
503 wallify_vault(grd);
504 egrd->gddone = 1;
505 goto cleanup;
506 }
507 }
508 }
509
510 if(egrd->fcend > 1) {
511 if(egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
512 !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
513 levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
514 == egrd->fakecorr[0].ftyp) {
515 pline_The("guard, confused, disappears.");
516 disappear_msg_seen = TRUE;
517 goto cleanup;
518 }
519 if(u_carry_gold &&
520 (in_fcorridor(grd, u.ux, u.uy) ||
521 /* cover a 'blind' spot */
522 (egrd->fcend > 1 && u_in_vault))) {
523 if(!grd->mx) {
524 restfakecorr(grd);
525 return(-2);
526 }
527 if(egrd->warncnt < 6) {
528 egrd->warncnt = 6;
529 verbalize("Drop all your gold, scoundrel!");
530 return(0);
531 } else {
532 verbalize("So be it, rogue!");
533 grd->mpeaceful = 0;
534 return(-1);
535 }
536 }
537 }
538 for(fci = egrd->fcbeg; fci < egrd->fcend; fci++)
539 if(g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)){
540 m = egrd->fakecorr[fci].fx;
541 n = egrd->fakecorr[fci].fy;
542 goldincorridor = TRUE;
543 }
544 if(goldincorridor && !egrd->gddone) {
545 x = grd->mx;
546 y = grd->my;
547 if (m == u.ux && n == u.uy) {
548 struct obj *gold = g_at(m,n);
549 /* Grab the gold from between the hero's feet. */
550 grd->mgold += gold->quan;
551 delobj(gold);
552 newsym(m,n);
553 } else if (m == x && n == y) {
554 mpickgold(grd); /* does a newsym */
555 } else {
556 /* just for insurance... */
557 if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
558 verbalize("Out of my way, scum!");
559 rloc(m_at(m, n));
560 }
561 remove_monster(grd->mx, grd->my);
562 newsym(grd->mx, grd->my);
563 place_monster(grd, m, n);
564 mpickgold(grd); /* does a newsym */
565 }
566 if(cansee(m,n))
567 pline("%s%s picks up the gold.", Monnam(grd),
568 grd->mpeaceful ? " calms down and" : "");
569 if(x != grd->mx || y != grd->my) {
570 remove_monster(grd->mx, grd->my);
571 newsym(grd->mx, grd->my);
572 place_monster(grd, x, y);
573 newsym(x, y);
574 }
575 if(!grd->mpeaceful) return(-1);
576 else {
577 egrd->warncnt = 5;
578 return(0);
579 }
580 }
581 if(um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
582 if(!egrd->gddone && !rn2(10)) verbalize("Move along!");
583 restfakecorr(grd);
584 return(0); /* didn't move */
585 }
586 x = grd->mx;
587 y = grd->my;
588
589 if(u_in_vault) goto nextpos;
590
591 /* look around (hor & vert only) for accessible places */
592 for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
593 if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {
594
595 typ = (crm = &levl[nx][ny])->typ;
596 if(!IS_STWALL(typ) && !IS_POOL(typ)) {
597
598 if(in_fcorridor(grd, nx, ny))
599 goto nextnxy;
600
601 if(*in_rooms(nx,ny,VAULT))
602 continue;
603
604 /* seems we found a good place to leave him alone */
605 egrd->gddone = 1;
606 if(ACCESSIBLE(typ)) goto newpos;
607 #ifdef STUPID
608 if (typ == SCORR)
609 crm->typ = CORR;
610 else
611 crm->typ = DOOR;
612 #else
613 crm->typ = (typ == SCORR) ? CORR : DOOR;
614 #endif
615 if(crm->typ == DOOR) crm->doormask = D_NODOOR;
616 goto proceed;
617 }
618 }
619 nextnxy: ;
620 }
621 nextpos:
622 nx = x;
623 ny = y;
624 gx = egrd->gdx;
625 gy = egrd->gdy;
626 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
627 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
628 if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
629
630 while((typ = (crm = &levl[nx][ny])->typ) != 0) {
631 /* in view of the above we must have IS_WALL(typ) or typ == POOL */
632 /* must be a wall here */
633 if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) &&
634 IS_ROOM(levl[nx+nx-x][ny+ny-y].typ)){
635 crm->typ = DOOR;
636 crm->doormask = D_NODOOR;
637 goto proceed;
638 }
639 if(dy && nx != x) {
640 nx = x; ny = y+dy;
641 continue;
642 }
643 if(dx && ny != y) {
644 ny = y; nx = x+dx; dy = 0;
645 continue;
646 }
647 /* I don't like this, but ... */
648 if(IS_ROOM(typ)) {
649 crm->typ = DOOR;
650 crm->doormask = D_NODOOR;
651 goto proceed;
652 }
653 break;
654 }
655 crm->typ = CORR;
656 proceed:
657 unblock_point(nx, ny); /* doesn't block light */
658 if (cansee(nx,ny))
659 newsym(nx,ny);
660
661 fcp = &(egrd->fakecorr[egrd->fcend]);
662 if(egrd->fcend++ == FCSIZ) panic("fakecorr overflow");
663 fcp->fx = nx;
664 fcp->fy = ny;
665 fcp->ftyp = typ;
666 newpos:
667 if(egrd->gddone) {
668 /* The following is a kludge. We need to keep */
669 /* the guard around in order to be able to make */
670 /* the fake corridor disappear as the player */
671 /* moves out of it, but we also need the guard */
672 /* out of the way. We send the guard to never- */
673 /* never land. We set ogx ogy to mx my in order */
674 /* to avoid a check at the top of this function. */
675 /* At the end of the process, the guard is killed */
676 /* in restfakecorr(). */
677 cleanup:
678 x = grd->mx; y = grd->my;
679
680 wallify_vault(grd);
681 remove_monster(grd->mx, grd->my);
682 newsym(grd->mx,grd->my);
683 place_monster(grd, 0, 0);
684 egrd->ogx = grd->mx;
685 egrd->ogy = grd->my;
686 restfakecorr(grd);
687 if(!semi_dead && (in_fcorridor(grd, u.ux, u.uy) ||
688 cansee(x, y))) {
689 if (!disappear_msg_seen)
690 pline("Suddenly, the guard disappears.");
691 return(1);
692 }
693 return(-2);
694 }
695 egrd->ogx = grd->mx; /* update old positions */
696 egrd->ogy = grd->my;
697 remove_monster(grd->mx, grd->my);
698 place_monster(grd, nx, ny);
699 newsym(grd->mx,grd->my);
700 restfakecorr(grd);
701 return(1);
702 }
703
704 /* Routine when dying or quitting with a vault guard around */
705 void
paygd()706 paygd()
707 {
708 register struct monst *grd = findgd();
709 struct obj *gold;
710 int gx,gy;
711 char buf[BUFSZ];
712
713 if (!u.ugold || !grd) return;
714
715 if (u.uinvault) {
716 Your("%ld zorkmid%s goes into the Magic Memory Vault.",
717 u.ugold, plur(u.ugold));
718 gx = u.ux;
719 gy = u.uy;
720 } else {
721 if(grd->mpeaceful) { /* guard has no "right" to your gold */
722 mongone(grd);
723 return;
724 }
725 mnexto(grd);
726 pline("%s remits your gold to the vault.", Monnam(grd));
727 gx = rooms[EGD(grd)->vroom].lx + rn2(2);
728 gy = rooms[EGD(grd)->vroom].ly + rn2(2);
729 Sprintf(buf,
730 "To Croesus: here's the gold recovered from %s the %s.",
731 plname, mons[u.umonster].mname);
732 make_grave(gx, gy, buf);
733 }
734 place_object(gold = mkgoldobj(u.ugold), gx, gy);
735 stackobj(gold);
736 mongone(grd);
737 }
738
739 long
hidden_gold()740 hidden_gold()
741 {
742 register long value = 0L;
743 register struct obj *obj;
744
745 for (obj = invent; obj; obj = obj->nobj)
746 if (Has_contents(obj))
747 value += contained_gold(obj);
748 /* unknown gold stuck inside statues may cause some consternation... */
749
750 return(value);
751 }
752
753 boolean
gd_sound()754 gd_sound() /* prevent "You hear footsteps.." when inappropriate */
755 {
756 register struct monst *grd = findgd();
757
758 if (vault_occupied(u.urooms)) return(FALSE);
759 else return((boolean)(grd == (struct monst *)0));
760 }
761
762 #endif /* OVLB */
763
764 /*vault.c*/
765