1 /* $NetBSD: hack.vault.c,v 1.7 2004/01/27 20:30:29 jsm Exp $ */ 2 3 /* 4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, 5 * Amsterdam 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are 10 * met: 11 * 12 * - Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * - Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * - Neither the name of the Stichting Centrum voor Wiskunde en 20 * Informatica, nor the names of its contributors may be used to endorse or 21 * promote products derived from this software without specific prior 22 * written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 /* 38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org> 39 * All rights reserved. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. The name of the author may not be used to endorse or promote products 50 * derived from this software without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 #include <sys/cdefs.h> 65 #ifndef lint 66 __RCSID("$NetBSD: hack.vault.c,v 1.7 2004/01/27 20:30:29 jsm Exp $"); 67 #endif /* not lint */ 68 69 #include "hack.h" 70 #include "extern.h" 71 #ifdef QUEST 72 void 73 setgd( /* mtmp */ ) 74 { /* struct monst *mtmp; */ 75 } 76 int 77 gd_move() { 78 return (2); 79 } 80 void 81 gddead() 82 { 83 } 84 void 85 replgd(mtmp, mtmp2) 86 struct monst *mtmp, *mtmp2; 87 { 88 } 89 void 90 invault() 91 { 92 } 93 94 #else 95 96 97 #include "def.mkroom.h" 98 #define FCSIZ (ROWNO+COLNO) 99 struct fakecorridor { 100 xchar fx, fy, ftyp; 101 }; 102 103 struct egd { 104 int fcbeg, fcend; /* fcend: first unused pos */ 105 xchar gdx, gdy; /* goal of guard's walk */ 106 unsigned gddone:1; 107 struct fakecorridor fakecorr[FCSIZ]; 108 }; 109 110 static const struct permonst pm_guard = 111 {"guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd)}; 112 113 static struct monst *guard; 114 static int gdlevel; 115 #define EGD ((struct egd *)(&(guard->mextra[0]))) 116 117 static void restfakecorr(void); 118 static int goldincorridor(void); 119 120 static void 121 restfakecorr() 122 { 123 int fcx, fcy, fcbeg; 124 struct rm *crm; 125 126 while ((fcbeg = EGD->fcbeg) < EGD->fcend) { 127 fcx = EGD->fakecorr[fcbeg].fx; 128 fcy = EGD->fakecorr[fcbeg].fy; 129 if ((u.ux == fcx && u.uy == fcy) || cansee(fcx, fcy) || 130 m_at(fcx, fcy)) 131 return; 132 crm = &levl[fcx][fcy]; 133 crm->typ = EGD->fakecorr[fcbeg].ftyp; 134 if (!crm->typ) 135 crm->seen = 0; 136 newsym(fcx, fcy); 137 EGD->fcbeg++; 138 } 139 /* it seems he left the corridor - let the guard disappear */ 140 mondead(guard); 141 guard = 0; 142 } 143 144 static int 145 goldincorridor() 146 { 147 int fci; 148 149 for (fci = EGD->fcbeg; fci < EGD->fcend; fci++) 150 if (g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy)) 151 return (1); 152 return (0); 153 } 154 155 void 156 setgd() 157 { 158 struct monst *mtmp; 159 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 160 if (mtmp->isgd) { 161 guard = mtmp; 162 gdlevel = dlevel; 163 return; 164 } 165 guard = 0; 166 } 167 168 void 169 invault() 170 { 171 int tmp = inroom(u.ux, u.uy); 172 if (tmp < 0 || rooms[tmp].rtype != VAULT) { 173 u.uinvault = 0; 174 return; 175 } 176 if (++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) { 177 char buf[BUFSZ]; 178 int x, y, dd, gx, gy; 179 180 /* first find the goal for the guard */ 181 for (dd = 1; (dd < ROWNO || dd < COLNO); dd++) { 182 for (y = u.uy - dd; y <= u.uy + dd; y++) { 183 if (y < 0 || y > ROWNO - 1) 184 continue; 185 for (x = u.ux - dd; x <= u.ux + dd; x++) { 186 if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd) 187 x = u.ux + dd; 188 if (x < 0 || x > COLNO - 1) 189 continue; 190 if (levl[x][y].typ == CORR) 191 goto fnd; 192 } 193 } 194 } 195 impossible("Not a single corridor on this level??"); 196 tele(); 197 return; 198 fnd: 199 gx = x; 200 gy = y; 201 202 /* next find a good place for a door in the wall */ 203 x = u.ux; 204 y = u.uy; 205 while (levl[x][y].typ == ROOM) { 206 int dx, dy; 207 208 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; 209 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; 210 if (abs(gx - x) >= abs(gy - y)) 211 x += dx; 212 else 213 y += dy; 214 } 215 216 /* make something interesting happen */ 217 if (!(guard = makemon(&pm_guard, x, y))) 218 return; 219 guard->isgd = guard->mpeaceful = 1; 220 EGD->gddone = 0; 221 gdlevel = dlevel; 222 if (!cansee(guard->mx, guard->my)) { 223 mondead(guard); 224 guard = 0; 225 return; 226 } 227 pline("Suddenly one of the Vault's guards enters!"); 228 pmon(guard); 229 do { 230 pline("\"Hello stranger, who are you?\" - "); 231 getlin(buf); 232 } while (!letter(buf[0])); 233 234 if (!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) { 235 pline("\"Oh, yes - of course. Sorry to have disturbed you.\""); 236 mondead(guard); 237 guard = 0; 238 return; 239 } 240 clrlin(); 241 pline("\"I don't know you.\""); 242 if (!u.ugold) 243 pline("\"Please follow me.\""); 244 else { 245 pline("\"Most likely all that gold was stolen from this vault.\""); 246 pline("\"Please drop your gold (say d$ ) and follow me.\""); 247 } 248 EGD->gdx = gx; 249 EGD->gdy = gy; 250 EGD->fcbeg = 0; 251 EGD->fakecorr[0].fx = x; 252 EGD->fakecorr[0].fy = y; 253 EGD->fakecorr[0].ftyp = levl[x][y].typ; 254 levl[x][y].typ = DOOR; 255 EGD->fcend = 1; 256 } 257 } 258 259 int 260 gd_move() 261 { 262 int x, y, dx, dy, gx, gy, nx, ny, typ; 263 struct fakecorridor *fcp; 264 struct rm *crm; 265 if (!guard || gdlevel != dlevel) { 266 impossible("Where is the guard?"); 267 return (2); /* died */ 268 } 269 if (u.ugold || goldincorridor()) 270 return (0); /* didnt move */ 271 if (dist(guard->mx, guard->my) > 1 || EGD->gddone) { 272 restfakecorr(); 273 return (0); /* didnt move */ 274 } 275 x = guard->mx; 276 y = guard->my; 277 /* look around (hor & vert only) for accessible places */ 278 for (nx = x - 1; nx <= x + 1; nx++) 279 for (ny = y - 1; ny <= y + 1; ny++) { 280 if (nx == x || ny == y) 281 if (nx != x || ny != y) 282 if (isok(nx, ny)) 283 if (!IS_WALL(typ = (crm = &levl[nx][ny])->typ) && typ != POOL) { 284 int i; 285 for (i = EGD->fcbeg; i < EGD->fcend; i++) 286 if (EGD->fakecorr[i].fx == nx && 287 EGD->fakecorr[i].fy == ny) 288 goto nextnxy; 289 if ((i = inroom(nx, ny)) >= 0 && rooms[i].rtype == VAULT) 290 goto nextnxy; 291 /* 292 * seems we found a 293 * good place to 294 * leave him alone 295 */ 296 EGD->gddone = 1; 297 if (ACCESSIBLE(typ)) 298 goto newpos; 299 crm->typ = (typ == SCORR) ? CORR : DOOR; 300 goto proceed; 301 } 302 nextnxy: ; 303 } 304 nx = x; 305 ny = y; 306 gx = EGD->gdx; 307 gy = EGD->gdy; 308 dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; 309 dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; 310 if (abs(gx - x) >= abs(gy - y)) 311 nx += dx; 312 else 313 ny += dy; 314 315 while ((typ = (crm = &levl[nx][ny])->typ) != 0) { 316 /* 317 * in view of the above we must have IS_WALL(typ) or typ == 318 * POOL 319 */ 320 /* must be a wall here */ 321 if (isok(nx + nx - x, ny + ny - y) && typ != POOL && 322 ZAP_POS(levl[nx + nx - x][ny + ny - y].typ)) { 323 crm->typ = DOOR; 324 goto proceed; 325 } 326 if (dy && nx != x) { 327 nx = x; 328 ny = y + dy; 329 continue; 330 } 331 if (dx && ny != y) { 332 ny = y; 333 nx = x + dx; 334 dy = 0; 335 continue; 336 } 337 /* I don't like this, but ... */ 338 crm->typ = DOOR; 339 goto proceed; 340 } 341 crm->typ = CORR; 342 proceed: 343 if (cansee(nx, ny)) { 344 mnewsym(nx, ny); 345 prl(nx, ny); 346 } 347 fcp = &(EGD->fakecorr[EGD->fcend]); 348 if (EGD->fcend++ == FCSIZ) 349 panic("fakecorr overflow"); 350 fcp->fx = nx; 351 fcp->fy = ny; 352 fcp->ftyp = typ; 353 newpos: 354 if (EGD->gddone) 355 nx = ny = 0; 356 guard->mx = nx; 357 guard->my = ny; 358 pmon(guard); 359 restfakecorr(); 360 return (1); 361 } 362 363 void 364 gddead() 365 { 366 guard = 0; 367 } 368 369 void 370 replgd(mtmp, mtmp2) 371 struct monst *mtmp, *mtmp2; 372 { 373 if (mtmp == guard) 374 guard = mtmp2; 375 } 376 377 #endif /* QUEST */ 378