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