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. */ 4 5#include "hack.h" 6#include "vault.h" 7 8STATIC_DCL struct monst *NDECL(findgd); 9 10#define g_monnam(mtmp) \ 11 x_monnam(mtmp, ARTICLE_NONE, (char *)0, SUPPRESS_IT, FALSE) 12 13#ifdef OVLB 14 15STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *,BOOLEAN_P)); 16STATIC_DCL void FDECL(restfakecorr,(struct monst *)); 17STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *,int,int)); 18STATIC_DCL void FDECL(move_gold,(struct obj *,int)); 19STATIC_DCL void FDECL(wallify_vault,(struct monst *)); 20 21STATIC_OVL boolean 22clear_fcorr(grd, forceshow) 23register struct monst *grd; 24register boolean forceshow; 25{ 26 register int fcx, fcy, fcbeg; 27 register struct monst *mtmp; 28 29 if (!on_level(&(EGD(grd)->gdlevel), &u.uz)) return TRUE; 30 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; 42 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); 48 } 49 } 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++; 54 } 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."); 58 } 59 return(TRUE); 60} 61 62STATIC_OVL void 63restfakecorr(grd) 64register struct monst *grd; 65{ 66 /* it seems you left the corridor - let the guard disappear */ 67 if(clear_fcorr(grd, FALSE)) mongone(grd); 68} 69 70boolean 71grddead(grd) /* called in mon.c */ 72register struct monst *grd; 73{ 74 register boolean dispose = clear_fcorr(grd, TRUE); 75 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); 84 } 85 return(dispose); 86} 87 88STATIC_OVL boolean 89in_fcorridor(grd, x, y) 90register struct monst *grd; 91int x, y; 92{ 93 register int fci; 94 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); 100} 101 102STATIC_OVL 103struct monst * 104findgd() 105{ 106 register struct monst *mtmp; 107 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); 112} 113 114#endif /* OVLB */ 115#ifdef OVL0 116 117char 118vault_occupied(array) 119char *array; 120{ 121 register char *ptr; 122 123 for (ptr = array; *ptr; ptr++) 124 if (rooms[*ptr - ROOMOFFSET].rtype == VAULT) 125 return(*ptr); 126 return('\0'); 127} 128 129void 130invault() 131{ 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); 137 138 if(!vaultroom) { 139 u.uinvault = 0; 140 return; 141 } 142 143 vaultroom -= ROOMOFFSET; 144 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; 171 } 172 } 173 } 174incr_radius: ; 175 } 176 impossible("Not a single corridor on this level??"); 177 tele(); 178 return; 179fnd: 180 gx = x; gy = y; 181 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; 201 } 202 } 203 while(levl[x][y].typ == ROOM) { 204 register int dx,dy; 205 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; 212 } 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; 223 } 224 225 /* make something interesting happen */ 226 if(!(guard = makemon(&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; 236 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; 252 } 253 if (Strangled || is_silent(youmonst.data) || multi < 0) { 254 /* [we ought to record whether this this message has already 255 been given in order to vary it upon repeat visits, but 256 discarding the monster and its egd data renders that hard] */ 257 verbalize("I'll be back when you're ready to speak to me!"); 258 mongone(guard); 259 return; 260 } 261 262 stop_occupation(); /* if occupied, stop it *now* */ 263 if (multi > 0) { nomul(0); unmul((char *)0); } 264 trycount = 5; 265 do { 266 getlin("\"Hello stranger, who are you?\" -", buf); 267 (void) mungspaces(buf); 268 } while (!letter(buf[0]) && --trycount > 0); 269 270 if (u.ualign.type == A_LAWFUL && 271 /* ignore trailing text, in case player includes character's rank */ 272 strncmpi(buf, plname, (int) strlen(plname)) != 0) { 273 adjalign(-1); /* Liar! */ 274 } 275 276 if (!strcmpi(buf, "Croesus") || !strcmpi(buf, "Kroisos") 277#ifdef TOURIST 278 || !strcmpi(buf, "Creosote") 279#endif 280 ) { 281 if (!mvitals[PM_CROESUS].died) { 282 verbalize("Oh, yes, of course. Sorry to have disturbed you."); 283 mongone(guard); 284 } else { 285 setmangry(guard); 286 verbalize("Back from the dead, are you? I'll remedy that!"); 287 /* don't want guard to waste next turn wielding a weapon */ 288 if (!MON_WEP(guard)) { 289 guard->weapon_check = NEED_HTH_WEAPON; 290 (void) mon_wield_item(guard); 291 } 292 } 293 return; 294 } 295 verbalize("I don't know you."); 296#ifndef GOLDOBJ 297 if (!u.ugold && !hidden_gold()) 298 verbalize("Please follow me."); 299 else { 300 if (!u.ugold) 301 verbalize("You have hidden gold."); 302 verbalize("Most likely all your gold was stolen from this vault."); 303 verbalize("Please drop that gold and follow me."); 304 } 305#else 306 umoney = money_cnt(invent); 307 if (!umoney && !hidden_gold()) 308 verbalize("Please follow me."); 309 else { 310 if (!umoney) 311 verbalize("You have hidden money."); 312 verbalize("Most likely all your money was stolen from this vault."); 313 verbalize("Please drop that money and follow me."); 314 } 315#endif 316 EGD(guard)->gdx = gx; 317 EGD(guard)->gdy = gy; 318 EGD(guard)->fcbeg = 0; 319 EGD(guard)->fakecorr[0].fx = x; 320 EGD(guard)->fakecorr[0].fy = y; 321 if(IS_WALL(levl[x][y].typ)) 322 EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ; 323 else { /* the initial guard location is a dug door */ 324 int vlt = EGD(guard)->vroom; 325 xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx; 326 xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy; 327 328 if(x == lowx-1 && y == lowy-1) 329 EGD(guard)->fakecorr[0].ftyp = TLCORNER; 330 else if(x == hix+1 && y == lowy-1) 331 EGD(guard)->fakecorr[0].ftyp = TRCORNER; 332 else if(x == lowx-1 && y == hiy+1) 333 EGD(guard)->fakecorr[0].ftyp = BLCORNER; 334 else if(x == hix+1 && y == hiy+1) 335 EGD(guard)->fakecorr[0].ftyp = BRCORNER; 336 else if(y == lowy-1 || y == hiy+1) 337 EGD(guard)->fakecorr[0].ftyp = HWALL; 338 else if(x == lowx-1 || x == hix+1) 339 EGD(guard)->fakecorr[0].ftyp = VWALL; 340 } 341 levl[x][y].typ = DOOR; 342 levl[x][y].doormask = D_NODOOR; 343 unblock_point(x, y); /* doesn't block light */ 344 EGD(guard)->fcend = 1; 345 EGD(guard)->warncnt = 1; 346 } 347} 348 349#endif /* OVL0 */ 350#ifdef OVLB 351 352STATIC_OVL void 353move_gold(gold, vroom) 354struct obj *gold; 355int vroom; 356{ 357 xchar nx, ny; 358 359 remove_object(gold); 360 newsym(gold->ox, gold->oy); 361 nx = rooms[vroom].lx + rn2(2); 362 ny = rooms[vroom].ly + rn2(2); 363 place_object(gold, nx, ny); 364 stackobj(gold); 365 newsym(nx,ny); 366} 367 368STATIC_OVL void 369wallify_vault(grd) 370struct monst *grd; 371{ 372 int x, y, typ; 373 int vlt = EGD(grd)->vroom; 374 char tmp_viz; 375 xchar lox = rooms[vlt].lx - 1, hix = rooms[vlt].hx + 1, 376 loy = rooms[vlt].ly - 1, hiy = rooms[vlt].hy + 1; 377 struct monst *mon; 378 struct obj *gold; 379 struct trap *trap; 380 boolean fixed = FALSE; 381 boolean movedgold = FALSE; 382 383 for (x = lox; x <= hix; x++) 384 for (y = loy; y <= hiy; y++) { 385 /* if not on the room boundary, skip ahead */ 386 if (x != lox && x != hix && y != loy && y != hiy) continue; 387 388 if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) { 389 if ((mon = m_at(x, y)) != 0 && mon != grd) { 390 if (mon->mtame) yelp(mon); 391 (void) rloc(mon, FALSE); 392 } 393 if ((gold = g_at(x, y)) != 0) { 394 move_gold(gold, EGD(grd)->vroom); 395 movedgold = TRUE; 396 } 397 if ((trap = t_at(x, y)) != 0) 398 deltrap(trap); 399 if (x == lox) 400 typ = (y == loy) ? TLCORNER : 401 (y == hiy) ? BLCORNER : VWALL; 402 else if (x == hix) 403 typ = (y == loy) ? TRCORNER : 404 (y == hiy) ? BRCORNER : VWALL; 405 else /* not left or right side, must be top or bottom */ 406 typ = HWALL; 407 levl[x][y].typ = typ; 408 levl[x][y].doormask = 0; 409 /* 410 * hack: player knows walls are restored because of the 411 * message, below, so show this on the screen. 412 */ 413 tmp_viz = viz_array[y][x]; 414 viz_array[y][x] = IN_SIGHT|COULD_SEE; 415 newsym(x,y); 416 viz_array[y][x] = tmp_viz; 417 block_point(x,y); 418 fixed = TRUE; 419 } 420 } 421 422 if(movedgold || fixed) { 423 if(in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my)) 424 pline_The("%s whispers an incantation.", g_monnam(grd)); 425 else You_hear("a distant chant."); 426 if(movedgold) 427 pline("A mysterious force moves the gold into the vault."); 428 if(fixed) 429 pline_The("damaged vault's walls are magically restored!"); 430 } 431} 432 433/* 434 * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died 435 */ 436int 437gd_move(grd) 438register struct monst *grd; 439{ 440 int x, y, nx, ny, m, n; 441 int dx, dy, gx, gy, fci; 442 uchar typ; 443 struct fakecorridor *fcp; 444 register struct egd *egrd = EGD(grd); 445 register struct rm *crm; 446 register boolean goldincorridor = FALSE, 447 u_in_vault = vault_occupied(u.urooms)? TRUE : FALSE, 448 grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT)? 449 TRUE : FALSE; 450 boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0); 451#ifndef GOLDOBJ 452 register boolean u_carry_gold = ((u.ugold + hidden_gold()) > 0L); 453#else 454 long umoney = money_cnt(invent); 455 register boolean u_carry_gold = ((umoney + hidden_gold()) > 0L); 456#endif 457 boolean see_guard; 458 459 if(!on_level(&(egrd->gdlevel), &u.uz)) return(-1); 460 nx = ny = m = n = 0; 461 if(!u_in_vault && !grd_in_vault) 462 wallify_vault(grd); 463 if(!grd->mpeaceful) { 464 if(semi_dead) { 465 egrd->gddone =1; 466 goto newpos; 467 } 468 if(!u_in_vault && 469 (grd_in_vault || 470 (in_fcorridor(grd, grd->mx, grd->my) && 471 !in_fcorridor(grd, u.ux, u.uy)))) { 472 (void) rloc(grd, FALSE); 473 wallify_vault(grd); 474 (void) clear_fcorr(grd, TRUE); 475 goto letknow; 476 } 477 if(!in_fcorridor(grd, grd->mx, grd->my)) 478 (void) clear_fcorr(grd, TRUE); 479 return(-1); 480 } 481 if(abs(egrd->ogx - grd->mx) > 1 || 482 abs(egrd->ogy - grd->my) > 1) 483 return(-1); /* teleported guard - treat as monster */ 484 if(egrd->fcend == 1) { 485 if(u_in_vault && 486 (u_carry_gold || um_dist(grd->mx, grd->my, 1))) { 487 if(egrd->warncnt == 3) 488 verbalize("I repeat, %sfollow me!", 489 u_carry_gold ? ( 490#ifndef GOLDOBJ 491 !u.ugold ? 492 "drop that hidden gold and " : 493 "drop that gold and ") : ""); 494#else 495 !umoney ? 496 "drop that hidden money and " : 497 "drop that money and ") : ""); 498#endif 499 if(egrd->warncnt == 7) { 500 m = grd->mx; 501 n = grd->my; 502 verbalize("You've been warned, knave!"); 503 mnexto(grd); 504 levl[m][n].typ = egrd->fakecorr[0].ftyp; 505 newsym(m,n); 506 grd->mpeaceful = 0; 507 return(-1); 508 } 509 /* not fair to get mad when (s)he's fainted or paralyzed */ 510 if(!is_fainted() && multi >= 0) egrd->warncnt++; 511 return(0); 512 } 513 514 if (!u_in_vault) { 515 if (u_carry_gold) { /* player teleported */ 516 m = grd->mx; 517 n = grd->my; 518 (void) rloc(grd, FALSE); 519 levl[m][n].typ = egrd->fakecorr[0].ftyp; 520 newsym(m,n); 521 grd->mpeaceful = 0; 522letknow: 523 if (!cansee(grd->mx, grd->my) || !mon_visible(grd)) 524 You_hear("the shrill sound of a guard's whistle."); 525 else 526 You(um_dist(grd->mx, grd->my, 2) ? 527 "see an angry %s approaching." : 528 "are confronted by an angry %s.", 529 g_monnam(grd)); 530 return(-1); 531 } else { 532 verbalize("Well, begone."); 533 wallify_vault(grd); 534 egrd->gddone = 1; 535 goto cleanup; 536 } 537 } 538 } 539 540 if(egrd->fcend > 1) { 541 if(egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) && 542 !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) && 543 levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ 544 == egrd->fakecorr[0].ftyp) { 545 pline_The("%s, confused, disappears.", g_monnam(grd)); 546 disappear_msg_seen = TRUE; 547 goto cleanup; 548 } 549 if(u_carry_gold && 550 (in_fcorridor(grd, u.ux, u.uy) || 551 /* cover a 'blind' spot */ 552 (egrd->fcend > 1 && u_in_vault))) { 553 if(!grd->mx) { 554 restfakecorr(grd); 555 return(-2); 556 } 557 if(egrd->warncnt < 6) { 558 egrd->warncnt = 6; 559 verbalize("Drop all your gold, scoundrel!"); 560 return(0); 561 } else { 562 verbalize("So be it, rogue!"); 563 grd->mpeaceful = 0; 564 return(-1); 565 } 566 } 567 } 568 for(fci = egrd->fcbeg; fci < egrd->fcend; fci++) 569 if(g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)){ 570 m = egrd->fakecorr[fci].fx; 571 n = egrd->fakecorr[fci].fy; 572 goldincorridor = TRUE; 573 } 574 if(goldincorridor && !egrd->gddone) { 575 x = grd->mx; 576 y = grd->my; 577 if (m == u.ux && n == u.uy) { 578 struct obj *gold = g_at(m,n); 579 /* Grab the gold from between the hero's feet. */ 580#ifndef GOLDOBJ 581 grd->mgold += gold->quan; 582 delobj(gold); 583#else 584 obj_extract_self(gold); 585 add_to_minv(grd, gold); 586#endif 587 newsym(m,n); 588 } else if (m == x && n == y) { 589 mpickgold(grd); /* does a newsym */ 590 } else { 591 /* just for insurance... */ 592 if (MON_AT(m, n) && m != grd->mx && n != grd->my) { 593 verbalize("Out of my way, scum!"); 594 (void) rloc(m_at(m, n), FALSE); 595 } 596 remove_monster(grd->mx, grd->my); 597 newsym(grd->mx, grd->my); 598 place_monster(grd, m, n); 599 mpickgold(grd); /* does a newsym */ 600 } 601 if(cansee(m,n)) 602 pline("%s%s picks up the gold.", Monnam(grd), 603 grd->mpeaceful ? " calms down and" : ""); 604 if(x != grd->mx || y != grd->my) { 605 remove_monster(grd->mx, grd->my); 606 newsym(grd->mx, grd->my); 607 place_monster(grd, x, y); 608 newsym(x, y); 609 } 610 if(!grd->mpeaceful) return(-1); 611 else { 612 egrd->warncnt = 5; 613 return(0); 614 } 615 } 616 if(um_dist(grd->mx, grd->my, 1) || egrd->gddone) { 617 if(!egrd->gddone && !rn2(10)) verbalize("Move along!"); 618 restfakecorr(grd); 619 return(0); /* didn't move */ 620 } 621 x = grd->mx; 622 y = grd->my; 623 624 if(u_in_vault) goto nextpos; 625 626 /* look around (hor & vert only) for accessible places */ 627 for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) { 628 if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) { 629 630 typ = (crm = &levl[nx][ny])->typ; 631 if(!IS_STWALL(typ) && !IS_POOL(typ)) { 632 633 if(in_fcorridor(grd, nx, ny)) 634 goto nextnxy; 635 636 if(*in_rooms(nx,ny,VAULT)) 637 continue; 638 639 /* seems we found a good place to leave him alone */ 640 egrd->gddone = 1; 641 if(ACCESSIBLE(typ)) goto newpos; 642#ifdef STUPID 643 if (typ == SCORR) 644 crm->typ = CORR; 645 else 646 crm->typ = DOOR; 647#else 648 crm->typ = (typ == SCORR) ? CORR : DOOR; 649#endif 650 if(crm->typ == DOOR) crm->doormask = D_NODOOR; 651 goto proceed; 652 } 653 } 654nextnxy: ; 655 } 656nextpos: 657 nx = x; 658 ny = y; 659 gx = egrd->gdx; 660 gy = egrd->gdy; 661 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; 662 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; 663 if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy; 664 665 while((typ = (crm = &levl[nx][ny])->typ) != 0) { 666 /* in view of the above we must have IS_WALL(typ) or typ == POOL */ 667 /* must be a wall here */ 668 if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) && 669 IS_ROOM(levl[nx+nx-x][ny+ny-y].typ)){ 670 crm->typ = DOOR; 671 crm->doormask = D_NODOOR; 672 goto proceed; 673 } 674 if(dy && nx != x) { 675 nx = x; ny = y+dy; 676 continue; 677 } 678 if(dx && ny != y) { 679 ny = y; nx = x+dx; dy = 0; 680 continue; 681 } 682 /* I don't like this, but ... */ 683 if(IS_ROOM(typ)) { 684 crm->typ = DOOR; 685 crm->doormask = D_NODOOR; 686 goto proceed; 687 } 688 break; 689 } 690 crm->typ = CORR; 691proceed: 692 unblock_point(nx, ny); /* doesn't block light */ 693 if (cansee(nx,ny)) 694 newsym(nx,ny); 695 696 fcp = &(egrd->fakecorr[egrd->fcend]); 697 if(egrd->fcend++ == FCSIZ) panic("fakecorr overflow"); 698 fcp->fx = nx; 699 fcp->fy = ny; 700 fcp->ftyp = typ; 701newpos: 702 if(egrd->gddone) { 703 /* The following is a kludge. We need to keep */ 704 /* the guard around in order to be able to make */ 705 /* the fake corridor disappear as the player */ 706 /* moves out of it, but we also need the guard */ 707 /* out of the way. We send the guard to never- */ 708 /* never land. We set ogx ogy to mx my in order */ 709 /* to avoid a check at the top of this function. */ 710 /* At the end of the process, the guard is killed */ 711 /* in restfakecorr(). */ 712cleanup: 713 x = grd->mx; y = grd->my; 714 715 see_guard = canspotmon(grd); 716 wallify_vault(grd); 717 remove_monster(grd->mx, grd->my); 718 newsym(grd->mx,grd->my); 719 place_monster(grd, 0, 0); 720 egrd->ogx = grd->mx; 721 egrd->ogy = grd->my; 722 restfakecorr(grd); 723 if(!semi_dead && (in_fcorridor(grd, u.ux, u.uy) || 724 cansee(x, y))) { 725 if (!disappear_msg_seen && see_guard) 726 pline("Suddenly, the %s disappears.", g_monnam(grd)); 727 return(1); 728 } 729 return(-2); 730 } 731 egrd->ogx = grd->mx; /* update old positions */ 732 egrd->ogy = grd->my; 733 remove_monster(grd->mx, grd->my); 734 place_monster(grd, nx, ny); 735 newsym(grd->mx,grd->my); 736 restfakecorr(grd); 737 return(1); 738} 739 740/* Routine when dying or quitting with a vault guard around */ 741void 742paygd() 743{ 744 register struct monst *grd = findgd(); 745#ifndef GOLDOBJ 746 struct obj *gold; 747#else 748 long umoney = money_cnt(invent); 749 struct obj *coins, *nextcoins; 750#endif 751 int gx,gy; 752 char buf[BUFSZ]; 753 754#ifndef GOLDOBJ 755 if (!u.ugold || !grd) return; 756#else 757 if (!umoney || !grd) return; 758#endif 759 760 if (u.uinvault) { 761 Your("%ld %s goes into the Magic Memory Vault.", 762#ifndef GOLDOBJ 763 u.ugold, 764 currency(u.ugold)); 765#else 766 umoney, 767 currency(umoney)); 768#endif 769 gx = u.ux; 770 gy = u.uy; 771 } else { 772 if(grd->mpeaceful) { /* guard has no "right" to your gold */ 773 mongone(grd); 774 return; 775 } 776 mnexto(grd); 777 pline("%s remits your gold to the vault.", Monnam(grd)); 778 gx = rooms[EGD(grd)->vroom].lx + rn2(2); 779 gy = rooms[EGD(grd)->vroom].ly + rn2(2); 780 Sprintf(buf, 781 "To Croesus: here's the gold recovered from %s the %s.", 782 plname, mons[u.umonster].mname); 783 make_grave(gx, gy, buf); 784 } 785#ifndef GOLDOBJ 786 place_object(gold = mkgoldobj(u.ugold), gx, gy); 787 stackobj(gold); 788#else 789 for (coins = invent; coins; coins = nextcoins) { 790 nextcoins = coins->nobj; 791 if (objects[coins->otyp].oc_class == COIN_CLASS) { 792 freeinv(coins); 793 place_object(coins, gx, gy); 794 stackobj(coins); 795 } 796 } 797#endif 798 mongone(grd); 799} 800 801long 802hidden_gold() 803{ 804 register long value = 0L; 805 register struct obj *obj; 806 807 for (obj = invent; obj; obj = obj->nobj) 808 if (Has_contents(obj)) 809 value += contained_gold(obj); 810 /* unknown gold stuck inside statues may cause some consternation... */ 811 812 return(value); 813} 814 815boolean 816gd_sound() /* prevent "You hear footsteps.." when inappropriate */ 817{ 818 register struct monst *grd = findgd(); 819 820 if (vault_occupied(u.urooms)) return(FALSE); 821 else return((boolean)(grd == (struct monst *)0)); 822} 823 824#endif /* OVLB */ 825 826/*vault.c*/ 827