1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2: /* hack.vault.c - version 1.0.2 */ 3: 4: #include "hack.h" 5: #ifdef QUEST 6: setgd(/* mtmp */) /* struct monst *mtmp; */ {} 7: gd_move() { return(2); } 8: gddead(mtmp) struct monst *mtmp; {} 9: replgd(mtmp,mtmp2) struct monst *mtmp, *mtmp2; {} 10: invault(){} 11: 12: #else 13: 14: 15: #include "def.mkroom.h" 16: extern struct monst *makemon(); 17: #define FCSIZ (ROWNO+COLNO) 18: struct fakecorridor { 19: xchar fx,fy,ftyp; 20: }; 21: 22: struct egd { 23: int fcbeg, fcend; /* fcend: first unused pos */ 24: xchar gdx, gdy; /* goal of guard's walk */ 25: unsigned gddone:1; 26: struct fakecorridor fakecorr[FCSIZ]; 27: }; 28: 29: static struct permonst pm_guard = 30: { "guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd) }; 31: 32: static struct monst *guard; 33: static int gdlevel; 34: #define EGD ((struct egd *)(&(guard->mextra[0]))) 35: 36: static 37: restfakecorr() 38: { 39: register fcx,fcy,fcbeg; 40: register struct rm *crm; 41: 42: while((fcbeg = EGD->fcbeg) < EGD->fcend) { 43: fcx = EGD->fakecorr[fcbeg].fx; 44: fcy = EGD->fakecorr[fcbeg].fy; 45: if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) || 46: m_at(fcx,fcy)) 47: return; 48: crm = &levl[fcx][fcy]; 49: crm->typ = EGD->fakecorr[fcbeg].ftyp; 50: if(!crm->typ) crm->seen = 0; 51: newsym(fcx,fcy); 52: EGD->fcbeg++; 53: } 54: /* it seems he left the corridor - let the guard disappear */ 55: mondead(guard); 56: guard = 0; 57: } 58: 59: static 60: goldincorridor() 61: { 62: register int fci; 63: 64: for(fci = EGD->fcbeg; fci < EGD->fcend; fci++) 65: if(g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy)) 66: return(1); 67: return(0); 68: } 69: 70: setgd(){ 71: register struct monst *mtmp; 72: for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){ 73: guard = mtmp; 74: gdlevel = dlevel; 75: return; 76: } 77: guard = 0; 78: } 79: 80: invault(){ 81: register tmp = inroom(u.ux, u.uy); 82: if(tmp < 0 || rooms[tmp].rtype != VAULT) { 83: u.uinvault = 0; 84: return; 85: } 86: if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) { 87: char buf[BUFSZ]; 88: register x,y,dd,gx,gy; 89: 90: /* first find the goal for the guard */ 91: for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) { 92: for(y = u.uy-dd; y <= u.uy+dd; y++) { 93: if(y < 0 || y > ROWNO-1) continue; 94: for(x = u.ux-dd; x <= u.ux+dd; x++) { 95: if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd) 96: x = u.ux+dd; 97: if(x < 0 || x > COLNO-1) continue; 98: if(levl[x][y].typ == CORR) goto fnd; 99: } 100: } 101: } 102: impossible("Not a single corridor on this level??"); 103: tele(); 104: return; 105: fnd: 106: gx = x; gy = y; 107: 108: /* next find a good place for a door in the wall */ 109: x = u.ux; y = u.uy; 110: while(levl[x][y].typ == ROOM) { 111: register int dx,dy; 112: 113: dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; 114: dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; 115: if(abs(gx-x) >= abs(gy-y)) 116: x += dx; 117: else 118: y += dy; 119: } 120: 121: /* make something interesting happen */ 122: if(!(guard = makemon(&pm_guard,x,y))) return; 123: guard->isgd = guard->mpeaceful = 1; 124: EGD->gddone = 0; 125: gdlevel = dlevel; 126: if(!cansee(guard->mx, guard->my)) { 127: mondead(guard); 128: guard = 0; 129: return; 130: } 131: 132: pline("Suddenly one of the Vault's guards enters!"); 133: pmon(guard); 134: do { 135: pline("\"Hello stranger, who are you?\" - "); 136: getlin(buf); 137: } while (!letter(buf[0])); 138: 139: if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) { 140: pline("\"Oh, yes - of course. Sorry to have disturbed you.\""); 141: mondead(guard); 142: guard = 0; 143: return; 144: } 145: clrlin(); 146: pline("\"I don't know you.\""); 147: if(!u.ugold) 148: pline("\"Please follow me.\""); 149: else { 150: pline("\"Most likely all that gold was stolen from this vault.\""); 151: pline("\"Please drop your gold (say d$ ) and follow me.\""); 152: } 153: EGD->gdx = gx; 154: EGD->gdy = gy; 155: EGD->fcbeg = 0; 156: EGD->fakecorr[0].fx = x; 157: EGD->fakecorr[0].fy = y; 158: EGD->fakecorr[0].ftyp = levl[x][y].typ; 159: levl[x][y].typ = DOOR; 160: EGD->fcend = 1; 161: } 162: } 163: 164: gd_move(){ 165: register int x,y,dx,dy,gx,gy,nx,ny,typ; 166: register struct fakecorridor *fcp; 167: register struct rm *crm; 168: if(!guard || gdlevel != dlevel){ 169: impossible("Where is the guard?"); 170: return(2); /* died */ 171: } 172: if(u.ugold || goldincorridor()) 173: return(0); /* didnt move */ 174: if(dist(guard->mx,guard->my) > 1 || EGD->gddone) { 175: restfakecorr(); 176: return(0); /* didnt move */ 177: } 178: x = guard->mx; 179: y = guard->my; 180: /* look around (hor & vert only) for accessible places */ 181: for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) { 182: if(nx == x || ny == y) if(nx != x || ny != y) 183: if(isok(nx,ny)) 184: if(!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) { 185: register int i; 186: for(i = EGD->fcbeg; i < EGD->fcend; i++) 187: if(EGD->fakecorr[i].fx == nx && 188: EGD->fakecorr[i].fy == ny) 189: goto nextnxy; 190: if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT) 191: goto nextnxy; 192: /* seems we found a good place to leave him alone */ 193: EGD->gddone = 1; 194: if(ACCESSIBLE(typ)) goto newpos; 195: crm->typ = (typ == SCORR) ? CORR : DOOR; 196: goto proceed; 197: } 198: nextnxy: ; 199: } 200: nx = x; 201: ny = y; 202: gx = EGD->gdx; 203: gy = EGD->gdy; 204: dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; 205: dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; 206: if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy; 207: 208: while((typ = (crm = &levl[nx][ny])->typ) != 0) { 209: /* in view of the above we must have IS_WALL(typ) or typ == POOL */ 210: /* must be a wall here */ 211: if(isok(nx+nx-x,ny+ny-y) && typ != POOL && 212: ZAP_POS(levl[nx+nx-x][ny+ny-y].typ)){ 213: crm->typ = DOOR; 214: goto proceed; 215: } 216: if(dy && nx != x) { 217: nx = x; ny = y+dy; 218: continue; 219: } 220: if(dx && ny != y) { 221: ny = y; nx = x+dx; dy = 0; 222: continue; 223: } 224: /* I don't like this, but ... */ 225: crm->typ = DOOR; 226: goto proceed; 227: } 228: crm->typ = CORR; 229: proceed: 230: if(cansee(nx,ny)) { 231: mnewsym(nx,ny); 232: prl(nx,ny); 233: } 234: fcp = &(EGD->fakecorr[EGD->fcend]); 235: if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow"); 236: fcp->fx = nx; 237: fcp->fy = ny; 238: fcp->ftyp = typ; 239: newpos: 240: if(EGD->gddone) nx = ny = 0; 241: guard->mx = nx; 242: guard->my = ny; 243: pmon(guard); 244: restfakecorr(); 245: return(1); 246: } 247: 248: gddead(){ 249: guard = 0; 250: } 251: 252: replgd(mtmp,mtmp2) 253: register struct monst *mtmp, *mtmp2; 254: { 255: if(mtmp == guard) 256: guard = mtmp2; 257: } 258: 259: #endif QUEST