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