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