This is vault.c in view mode; [Download] [Up]
/* SCCS Id: @(#)vault.c 3.0 88/10/25 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" #include "vault.h" static void FDECL(restfakecorr,(struct monst *)); OSTATIC boolean FDECL(in_vault,(int,int)); OSTATIC struct monst *NDECL(findgd); static boolean FDECL(in_fcorridor, (struct monst *,int,int)); #ifdef OVLB static void restfakecorr(grd) register struct monst *grd; { register int fcx, fcy, fcbeg; register struct rm *crm; while((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) { fcx = EGD(grd)->fakecorr[fcbeg].fx; fcy = EGD(grd)->fakecorr[fcbeg].fy; if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) || m_at(fcx,fcy)) return; crm = &levl[fcx][fcy]; crm->typ = EGD(grd)->fakecorr[fcbeg].ftyp; if(!crm->typ) crm->seen = 0; newsym(fcx,fcy); if(cansee(fcx,fcy)) prl(fcx,fcy); EGD(grd)->fcbeg++; } /* it seems he left the corridor - let the guard disappear */ mongone(grd); } static boolean in_fcorridor(grd, x, y) register struct monst *grd; int x, y; { register int fci; for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++) if(x == EGD(grd)->fakecorr[fci].fx && y == EGD(grd)->fakecorr[fci].fy) return(TRUE); return(FALSE); } XSTATIC struct monst * findgd() { register struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd && EGD(mtmp)->gdlevel == dlevel) return(mtmp); return((struct monst *)0); } #endif /* OVLB */ #ifdef OVL0 XSTATIC boolean in_vault(x, y) int x, y; { register int roomno = inroom(x, y); if(roomno < 0) return(FALSE); return(rooms[roomno].rtype == VAULT); } void invault() { #ifdef BSD_43_BUG int dummy; /* hack to avoid schain botch */ #endif struct monst *guard; if(!in_vault(u.ux, u.uy)) { u.uinvault = 0; return; } guard = findgd(); if(++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */ char buf[BUFSZ]; register int x, y, dd, gx, gy; /* first find the goal for the guard */ for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) { for(y = u.uy-dd; y <= u.uy+dd; y++) { if(y < 0 || y > ROWNO-1) continue; for(x = u.ux-dd; x <= u.ux+dd; x++) { if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd) x = u.ux+dd; if(x < 0 || x > COLNO-1) continue; if(levl[x][y].typ == CORR) goto fnd; } } } impossible("Not a single corridor on this level??"); tele(); return; fnd: gx = x; gy = y; /* next find a good place for a door in the wall */ x = u.ux; y = u.uy; while(levl[x][y].typ == ROOM) { register int dx,dy; dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; if(abs(gx-x) >= abs(gy-y)) x += dx; else y += dy; } /* make something interesting happen */ if(!(guard = makemon(&mons[PM_GUARD], x, y))) return; guard->isgd = 1; guard->mpeaceful = 1; EGD(guard)->gddone = 0; EGD(guard)->ogx = x; EGD(guard)->ogy = y; EGD(guard)->gdlevel = dlevel; EGD(guard)->warncnt = 0; if(!cansee(guard->mx, guard->my)) { mongone(guard); return; } reset_faint(); /* if fainted - wake up */ pline("Suddenly one of the Vault's guards enters!"); pmon(guard); stop_occupation(); /* if occupied, stop it *now* */ do { pline("\"Hello stranger, who are you?\" - "); getlin(buf); } while (!letter(buf[0])); if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) { verbalize("Oh, yes, of course. Sorry to have disturbed you."); mongone(guard); return; } clrlin(); verbalize("I don't know you."); if(!u.ugold) verbalize("Please follow me."); else { verbalize("Most likely all that gold was stolen from this vault."); verbalize("Please drop that gold and follow me."); } EGD(guard)->gdx = gx; EGD(guard)->gdy = gy; EGD(guard)->fcbeg = 0; EGD(guard)->fakecorr[0].fx = x; EGD(guard)->fakecorr[0].fy = y; EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ; levl[x][y].typ = DOOR; levl[x][y].doormask = D_NODOOR; EGD(guard)->fcend = 1; EGD(guard)->warncnt = 1; } } #endif /* OVL0 */ #ifdef OVLB /* * return 1: he moved, 0: he didn't, -1: let m_move do it, -2: died */ int gd_move(grd) register struct monst *grd; { int x, y, nx, ny, m, n; int dx, dy, gx, gy, i, fci; uchar typ; struct fakecorridor *fcp; register struct rm *crm; register struct gold *gold; register boolean goldincorridor = FALSE; #ifdef __GNULINT__ m = n = 0; #endif if(EGD(grd)->gdlevel != dlevel) return(-1); if(!grd->mpeaceful && in_vault(grd->mx, grd->my) && !in_vault(u.ux, u.uy)) { rloc(grd); goto letknow; } if(!grd->mpeaceful) return(-1); if(abs(EGD(grd)->ogx - grd->mx) > 1 || abs(EGD(grd)->ogy - grd->my) > 1) return(-1); /* teleported guard - treat as monster */ if(EGD(grd)->fcend == 1) { if(in_vault(u.ux, u.uy) && (u.ugold || um_dist(grd->mx, grd->my, 1))) { if(EGD(grd)->warncnt == 3) pline("\"Again, %sfollow me!\"", u.ugold ? "drop that gold and " : ""); if(EGD(grd)->warncnt == 6) { register int m = grd->mx, n = grd->my; verbalize("You've been warned, knave!"); mnexto(grd); levl[m][n].typ = EGD(grd)->fakecorr[0].ftyp; newsym(m,n); if(cansee(m,n)) prl(m,n); grd->mpeaceful = 0; return(-1); } /* not fair to get mad when (s)he's fainted */ if(!is_fainted()) EGD(grd)->warncnt++; return(0); } if(!in_vault(u.ux,u.uy) && u.ugold) { /* player teleported */ register int m = grd->mx, n = grd->my; rloc(grd); levl[m][n].typ = EGD(grd)->fakecorr[0].ftyp; newsym(m,n); if(!Blind) prl(m,n); grd->mpeaceful = 0; letknow: if(!cansee(grd->mx, grd->my)) You("hear the shrill sound of a guard's whistle."); else You(um_dist(grd->mx, grd->my, 2) ? "see an angry %s approaching." : "are confronted by an angry %s.", lmonnam(grd)+4); return(-1); } } if(u.ugold && (in_fcorridor(grd, u.ux, u.uy) || /*cover 'blind' spot*/ (EGD(grd)->fcend > 1 && in_vault(u.ux, u.uy)))) { if(EGD(grd)->warncnt < 6) { EGD(grd)->warncnt = 6; verbalize("Drop all your gold, scoundrel!"); return(0); } else { verbalize("So be it, rogue!"); grd->mpeaceful = 0; return(-1); } } for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++) if(g_at(EGD(grd)->fakecorr[fci].fx, EGD(grd)->fakecorr[fci].fy)){ m = EGD(grd)->fakecorr[fci].fx; n = EGD(grd)->fakecorr[fci].fy; goldincorridor = TRUE; } if(goldincorridor && !EGD(grd)->gddone) { x = grd->mx; y = grd->my; if(m == x && n == y) mpickgold(grd); else if(m == u.ux && n == u.uy) { gold = g_at(u.ux, u.uy); grd->mgold += gold->amount; freegold(gold); } else { /* just for insurance... */ if(MON_AT(m, n) && m != grd->mx && n != grd->my) { verbalize("Out of my way, scum!"); rloc(m_at(m, n)); } remove_monster(grd->mx, grd->my); place_monster(grd, m, n); pmon(grd); mpickgold(grd); } pline("The %s%s picks the gold.", lmonnam(grd)+4, grd->mpeaceful ? " calms down and" : ""); if(x != grd->mx || y != grd->my) { remove_monster(grd->mx, grd->my); place_monster(grd, x, y); pmon(grd); } goldincorridor = FALSE; if(!grd->mpeaceful) return(-1); else { EGD(grd)->warncnt = 5; return(0); } } if(um_dist(grd->mx, grd->my, 1) || EGD(grd)->gddone) { restfakecorr(grd); return(0); /* didn't move */ } x = grd->mx; y = grd->my; /* look around (hor & vert only) for accessible places */ for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) { if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) { typ = (crm = &levl[nx][ny])->typ; if(!IS_STWALL(typ) && !IS_POOL(typ)) { for(i = EGD(grd)->fcbeg; i < EGD(grd)->fcend; i++) if(EGD(grd)->fakecorr[i].fx == nx && EGD(grd)->fakecorr[i].fy == ny) goto nextnxy; if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT) continue; /* seems we found a good place to leave him alone */ EGD(grd)->gddone = 1; if(ACCESSIBLE(typ)) goto newpos; #ifdef STUPID if (typ == SCORR) crm->typ = CORR; else crm->typ = DOOR; #else crm->typ = (typ == SCORR) ? CORR : DOOR; #endif if(crm->typ == DOOR) crm->doormask = D_NODOOR; goto proceed; } } nextnxy: ; } nx = x; ny = y; gx = EGD(grd)->gdx; gy = EGD(grd)->gdy; dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy; while((typ = (crm = &levl[nx][ny])->typ) != 0) { /* in view of the above we must have IS_WALL(typ) or typ == POOL */ /* must be a wall here */ if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) && SPACE_POS(levl[nx+nx-x][ny+ny-y].typ)){ crm->typ = DOOR; crm->doormask = D_NODOOR; goto proceed; } if(dy && nx != x) { nx = x; ny = y+dy; continue; } if(dx && ny != y) { ny = y; nx = x+dx; dy = 0; continue; } /* I don't like this, but ... */ crm->typ = DOOR; crm->doormask = D_NODOOR; goto proceed; } crm->typ = CORR; proceed: if(cansee(nx,ny)) { mnewsym(nx,ny); prl(nx,ny); } fcp = &(EGD(grd)->fakecorr[EGD(grd)->fcend]); if(EGD(grd)->fcend++ == FCSIZ) panic("fakecorr overflow"); fcp->fx = nx; fcp->fy = ny; fcp->ftyp = typ; newpos: if(EGD(grd)->gddone) { /* The following is a kluge. We need to keep */ /* the guard around in order to be able to make */ /* the fake corridor disappear as the player */ /* moves out of it, but we also need the guard */ /* out of the way. We send the guard to never- */ /* never land. We set ogx ogy to mx my in order */ /* to avoid a check at the top of this function. */ /* At the end of the process, the guard is killed */ /* in restfakecorr(). */ remove_monster(grd->mx, grd->my); place_monster(grd, 0, 0); EGD(grd)->ogx = grd->mx; EGD(grd)->ogy = grd->my; restfakecorr(grd); if(in_fcorridor(grd, u.ux, u.uy) || cansee(grd->mx, grd->my)) pline("Suddenly, the guard disappears."); return(-2); } EGD(grd)->ogx = grd->mx; /* update old positions */ EGD(grd)->ogy = grd->my; remove_monster(grd->mx, grd->my); place_monster(grd, nx, ny); pmon(grd); restfakecorr(grd); return(1); } /* Routine when dying or quitting with a vault guard around */ void paygd() { struct monst *guard; register int i; int gx,gy; char buf[BUFSZ]; guard = findgd(); if (!u.ugold || !guard) return; if (u.uinvault) { Your("%ld zorkmid%s goes into the Magic Memory Vault.", u.ugold, plur(u.ugold)); mkgold(u.ugold, u.ux, u.uy); u.ugold = 0L; } else { if(guard->mpeaceful) { /* he has no "right" to your gold */ mongone(guard); return; } mnexto(guard); pmon(guard); pline("%s remits your gold to the vault.", Monnam(guard)); for(i=0; i<=nroom; i++) if (rooms[i].rtype==VAULT) break; if (i > nroom) { impossible("no vault?"); return; } gx = rooms[i].lx + rn2(2); gy = rooms[i].ly + rn2(2); mkgold(u.ugold, gx, gy); u.ugold = 0L; Sprintf(buf, "To Croesus: here's the gold recovered from the %s %s...", player_mon()->mname, plname); make_engr_at(gx, gy, buf); } mongone(guard); } boolean gd_sound() { /* prevent "You hear footsteps.." when inappropriate */ register struct monst *grd = findgd(); return(grd == (struct monst *)0); } #endif /* OVLB */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.