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

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

    1: /*      $NetBSD: hack.worm.c,v 1.5 2003/04/02 18:36:41 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.worm.c,v 1.5 2003/04/02 18:36:41 jsm Exp $");
   67: #endif                          /* not lint */
   68: 
   69: #include <stdlib.h>
   70: #include "hack.h"
   71: #include "extern.h"
   72: #ifndef NOWORM
   73: #include "def.wseg.h"
   74: 
   75: struct wseg    *wsegs[32];      /* linked list, tail first */
   76: struct wseg    *wheads[32];
   77: long            wgrowtime[32];
   78: 
   79: int
   80: getwn(mtmp)
   81:         struct monst   *mtmp;
   82: {
   83:         int    tmp;
   84:         for (tmp = 1; tmp < 32; tmp++)
   85:                 if (!wsegs[tmp]) {
   86:                         mtmp->wormno = tmp;
   87:                         return (1);
   88:                 }
   89:         return (0);            /* level infested with worms */
   90: }
   91: 
   92: /* called to initialize a worm unless cut in half */
   93: void
   94: initworm(mtmp)
   95:         struct monst   *mtmp;
   96: {
   97:         struct wseg    *wtmp;
   98:         int    tmp = mtmp->wormno;
   99:         if (!tmp)
  100:                 return;
  101:         wheads[tmp] = wsegs[tmp] = wtmp = newseg();
  102:         wgrowtime[tmp] = 0;
  103:         wtmp->wx = mtmp->mx;
  104:         wtmp->wy = mtmp->my;
  105:         /* wtmp->wdispl = 0; */
  106:         wtmp->nseg = 0;
  107: }
  108: 
  109: void
  110: worm_move(mtmp)
  111:         struct monst   *mtmp;
  112: {
  113:         struct wseg    *wtmp, *whd = NULL;
  114:         int            tmp = mtmp->wormno;
  115:         wtmp = newseg();
  116:         wtmp->wx = mtmp->mx;
  117:         wtmp->wy = mtmp->my;
  118:         wtmp->nseg = 0;
  119:         /* wtmp->wdispl = 0; */
  120:         (whd = wheads[tmp])->nseg = wtmp;
  121:         wheads[tmp] = wtmp;
  122:         if (cansee(whd->wx, whd->wy)) {
  123:                 unpmon(mtmp);
  124:                 atl(whd->wx, whd->wy, '~');
  125:                 whd->wdispl = 1;
  126:         } else
  127:                 whd->wdispl = 0;
  128:         if (wgrowtime[tmp] <= moves) {
  129:                 if (!wgrowtime[tmp])
  130:                         wgrowtime[tmp] = moves + rnd(5);
  131:                 else
  132:                         wgrowtime[tmp] += 2 + rnd(15);
  133:                 mtmp->mhpmax += 3;
  134:                 mtmp->mhp += 3;
  135:                 return;
  136:         }
  137:         whd = wsegs[tmp];
  138:         wsegs[tmp] = whd->nseg;
  139:         remseg(whd);
  140: }
  141: 
  142: void
  143: worm_nomove(mtmp)
  144:         struct monst   *mtmp;
  145: {
  146:         int            tmp;
  147:         struct wseg    *wtmp;
  148:         tmp = mtmp->wormno;
  149:         wtmp = wsegs[tmp];
  150:         if (wtmp == wheads[tmp])
  151:                 return;
  152:         if (wtmp == 0 || wtmp->nseg == 0)
  153:                 panic("worm_nomove?");
  154:         wsegs[tmp] = wtmp->nseg;
  155:         remseg(wtmp);
  156:         mtmp->mhp -= 3;                /* mhpmax not changed ! */
  157: }
  158: 
  159: void
  160: wormdead(mtmp)
  161:         struct monst   *mtmp;
  162: {
  163:         int            tmp = mtmp->wormno;
  164:         struct wseg    *wtmp, *wtmp2;
  165:         if (!tmp)
  166:                 return;
  167:         mtmp->wormno = 0;
  168:         for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) {
  169:                 wtmp2 = wtmp->nseg;
  170:                 remseg(wtmp);
  171:         }
  172:         wsegs[tmp] = 0;
  173: }
  174: 
  175: void
  176: wormhit(mtmp)
  177:         struct monst   *mtmp;
  178: {
  179:         int            tmp = mtmp->wormno;
  180:         struct wseg    *wtmp;
  181:         if (!tmp)
  182:                 return;               /* worm without tail */
  183:         for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
  184:                 (void) hitu(mtmp, 1);
  185: }
  186: 
  187: void
  188: wormsee(tmp)
  189:         unsigned        tmp;
  190: {
  191:         struct wseg    *wtmp = wsegs[tmp];
  192:         if (!wtmp)
  193:                 panic("wormsee: wtmp==0");
  194:         for (; wtmp->nseg; wtmp = wtmp->nseg)
  195:                 if (!cansee(wtmp->wx, wtmp->wy) && wtmp->wdispl) {
  196:                         newsym(wtmp->wx, wtmp->wy);
  197:                         wtmp->wdispl = 0;
  198:                 }
  199: }
  200: 
  201: void
  202: pwseg(wtmp)
  203:         struct wseg    *wtmp;
  204: {
  205:         if (!wtmp->wdispl) {
  206:                 atl(wtmp->wx, wtmp->wy, '~');
  207:                 wtmp->wdispl = 1;
  208:         }
  209: }
  210: 
  211: void
  212: cutworm(mtmp, x, y, weptyp)
  213:         struct monst   *mtmp;
  214:         xchar           x, y;
  215:         uchar           weptyp;        /* uwep->otyp or 0 */
  216: {
  217:         struct wseg    *wtmp, *wtmp2;
  218:         struct monst   *mtmp2;
  219:         int            tmp, tmp2;
  220:         if (mtmp->mx == x && mtmp->my == y)
  221:                 return;               /* hit headon */
  222: 
  223:         /* cutting goes best with axe or sword */
  224:         tmp = rnd(20);
  225:         if (weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
  226:             weptyp == AXE)
  227:                 tmp += 5;
  228:         if (tmp < 12)
  229:                 return;
  230: 
  231:         /* if tail then worm just loses a tail segment */
  232:         tmp = mtmp->wormno;
  233:         wtmp = wsegs[tmp];
  234:         if (wtmp->wx == x && wtmp->wy == y) {
  235:                 wsegs[tmp] = wtmp->nseg;
  236:                 remseg(wtmp);
  237:                 return;
  238:         }
  239:         /* cut the worm in two halves */
  240:         mtmp2 = newmonst(0);
  241:         *mtmp2 = *mtmp;
  242:         mtmp2->mxlth = mtmp2->mnamelth = 0;
  243: 
  244:         /* sometimes the tail end dies */
  245:         if (rn2(3) || !getwn(mtmp2)) {
  246:                 monfree(mtmp2);
  247:                 tmp2 = 0;
  248:         } else {
  249:                 tmp2 = mtmp2->wormno;
  250:                 wsegs[tmp2] = wsegs[tmp];
  251:                 wgrowtime[tmp2] = 0;
  252:         }
  253:         do {
  254:                 if (wtmp->nseg->wx == x && wtmp->nseg->wy == y) {
  255:                         if (tmp2)
  256:                                 wheads[tmp2] = wtmp;
  257:                         wsegs[tmp] = wtmp->nseg->nseg;
  258:                         remseg(wtmp->nseg);
  259:                         wtmp->nseg = 0;
  260:                         if (tmp2) {
  261:                                 pline("You cut the worm in half.");
  262:                                 mtmp2->mhpmax = mtmp2->mhp =
  263:                                         d(mtmp2->data->mlevel, 8);
  264:                                 mtmp2->mx = wtmp->wx;
  265:                                 mtmp2->my = wtmp->wy;
  266:                                 mtmp2->nmon = fmon;
  267:                                 fmon = mtmp2;
  268:                                 pmon(mtmp2);
  269:                         } else {
  270:                                 pline("You cut off part of the worm's tail.");
  271:                                 remseg(wtmp);
  272:                         }
  273:                         mtmp->mhp /= 2;
  274:                         return;
  275:                 }
  276:                 wtmp2 = wtmp->nseg;
  277:                 if (!tmp2)
  278:                         remseg(wtmp);
  279:                 wtmp = wtmp2;
  280:         } while (wtmp->nseg);
  281:         panic("Cannot find worm segment");
  282: }
  283: 
  284: void
  285: remseg(wtmp)
  286:         struct wseg    *wtmp;
  287: {
  288:         if (wtmp->wdispl)
  289:                 newsym(wtmp->wx, wtmp->wy);
  290:         free((char *) wtmp);
  291: }
  292: #endif  /* NOWORM */
Syntax (Markdown)