(linenum→info "unix/slp.c:2238")

bsd-games/2.17/hack/hack.vault.c

    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 */
Syntax (Markdown)