123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- /* $NetBSD: hack.worm.c,v 1.5 2003/04/02 18:36:41 jsm Exp $ */
- /*
- * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
- * Amsterdam
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of the Stichting Centrum voor Wiskunde en
- * Informatica, nor the names of its contributors may be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <sys/cdefs.h>
- #ifndef lint
- __RCSID("$NetBSD: hack.worm.c,v 1.5 2003/04/02 18:36:41 jsm Exp $");
- #endif /* not lint */
- #include <stdlib.h>
- #include "hack.h"
- #include "extern.h"
- #ifndef NOWORM
- #include "def.wseg.h"
- struct wseg *wsegs[32]; /* linked list, tail first */
- struct wseg *wheads[32];
- long wgrowtime[32];
- int
- getwn(mtmp)
- struct monst *mtmp;
- {
- int tmp;
- for (tmp = 1; tmp < 32; tmp++)
- if (!wsegs[tmp]) {
- mtmp->wormno = tmp;
- return (1);
- }
- return (0); /* level infested with worms */
- }
- /* called to initialize a worm unless cut in half */
- void
- initworm(mtmp)
- struct monst *mtmp;
- {
- struct wseg *wtmp;
- int tmp = mtmp->wormno;
- if (!tmp)
- return;
- wheads[tmp] = wsegs[tmp] = wtmp = newseg();
- wgrowtime[tmp] = 0;
- wtmp->wx = mtmp->mx;
- wtmp->wy = mtmp->my;
- /* wtmp->wdispl = 0; */
- wtmp->nseg = 0;
- }
- void
- worm_move(mtmp)
- struct monst *mtmp;
- {
- struct wseg *wtmp, *whd = NULL;
- int tmp = mtmp->wormno;
- wtmp = newseg();
- wtmp->wx = mtmp->mx;
- wtmp->wy = mtmp->my;
- wtmp->nseg = 0;
- /* wtmp->wdispl = 0; */
- (whd = wheads[tmp])->nseg = wtmp;
- wheads[tmp] = wtmp;
- if (cansee(whd->wx, whd->wy)) {
- unpmon(mtmp);
- atl(whd->wx, whd->wy, '~');
- whd->wdispl = 1;
- } else
- whd->wdispl = 0;
- if (wgrowtime[tmp] <= moves) {
- if (!wgrowtime[tmp])
- wgrowtime[tmp] = moves + rnd(5);
- else
- wgrowtime[tmp] += 2 + rnd(15);
- mtmp->mhpmax += 3;
- mtmp->mhp += 3;
- return;
- }
- whd = wsegs[tmp];
- wsegs[tmp] = whd->nseg;
- remseg(whd);
- }
- void
- worm_nomove(mtmp)
- struct monst *mtmp;
- {
- int tmp;
- struct wseg *wtmp;
- tmp = mtmp->wormno;
- wtmp = wsegs[tmp];
- if (wtmp == wheads[tmp])
- return;
- if (wtmp == 0 || wtmp->nseg == 0)
- panic("worm_nomove?");
- wsegs[tmp] = wtmp->nseg;
- remseg(wtmp);
- mtmp->mhp -= 3; /* mhpmax not changed ! */
- }
- void
- wormdead(mtmp)
- struct monst *mtmp;
- {
- int tmp = mtmp->wormno;
- struct wseg *wtmp, *wtmp2;
- if (!tmp)
- return;
- mtmp->wormno = 0;
- for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) {
- wtmp2 = wtmp->nseg;
- remseg(wtmp);
- }
- wsegs[tmp] = 0;
- }
- void
- wormhit(mtmp)
- struct monst *mtmp;
- {
- int tmp = mtmp->wormno;
- struct wseg *wtmp;
- if (!tmp)
- return; /* worm without tail */
- for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
- (void) hitu(mtmp, 1);
- }
- void
- wormsee(tmp)
- unsigned tmp;
- {
- struct wseg *wtmp = wsegs[tmp];
- if (!wtmp)
- panic("wormsee: wtmp==0");
- for (; wtmp->nseg; wtmp = wtmp->nseg)
- if (!cansee(wtmp->wx, wtmp->wy) && wtmp->wdispl) {
- newsym(wtmp->wx, wtmp->wy);
- wtmp->wdispl = 0;
- }
- }
- void
- pwseg(wtmp)
- struct wseg *wtmp;
- {
- if (!wtmp->wdispl) {
- atl(wtmp->wx, wtmp->wy, '~');
- wtmp->wdispl = 1;
- }
- }
- void
- cutworm(mtmp, x, y, weptyp)
- struct monst *mtmp;
- xchar x, y;
- uchar weptyp; /* uwep->otyp or 0 */
- {
- struct wseg *wtmp, *wtmp2;
- struct monst *mtmp2;
- int tmp, tmp2;
- if (mtmp->mx == x && mtmp->my == y)
- return; /* hit headon */
- /* cutting goes best with axe or sword */
- tmp = rnd(20);
- if (weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
- weptyp == AXE)
- tmp += 5;
- if (tmp < 12)
- return;
- /* if tail then worm just loses a tail segment */
- tmp = mtmp->wormno;
- wtmp = wsegs[tmp];
- if (wtmp->wx == x && wtmp->wy == y) {
- wsegs[tmp] = wtmp->nseg;
- remseg(wtmp);
- return;
- }
- /* cut the worm in two halves */
- mtmp2 = newmonst(0);
- *mtmp2 = *mtmp;
- mtmp2->mxlth = mtmp2->mnamelth = 0;
- /* sometimes the tail end dies */
- if (rn2(3) || !getwn(mtmp2)) {
- monfree(mtmp2);
- tmp2 = 0;
- } else {
- tmp2 = mtmp2->wormno;
- wsegs[tmp2] = wsegs[tmp];
- wgrowtime[tmp2] = 0;
- }
- do {
- if (wtmp->nseg->wx == x && wtmp->nseg->wy == y) {
- if (tmp2)
- wheads[tmp2] = wtmp;
- wsegs[tmp] = wtmp->nseg->nseg;
- remseg(wtmp->nseg);
- wtmp->nseg = 0;
- if (tmp2) {
- pline("You cut the worm in half.");
- mtmp2->mhpmax = mtmp2->mhp =
- d(mtmp2->data->mlevel, 8);
- mtmp2->mx = wtmp->wx;
- mtmp2->my = wtmp->wy;
- mtmp2->nmon = fmon;
- fmon = mtmp2;
- pmon(mtmp2);
- } else {
- pline("You cut off part of the worm's tail.");
- remseg(wtmp);
- }
- mtmp->mhp /= 2;
- return;
- }
- wtmp2 = wtmp->nseg;
- if (!tmp2)
- remseg(wtmp);
- wtmp = wtmp2;
- } while (wtmp->nseg);
- panic("Cannot find worm segment");
- }
- void
- remseg(wtmp)
- struct wseg *wtmp;
- {
- if (wtmp->wdispl)
- newsym(wtmp->wx, wtmp->wy);
- free((char *) wtmp);
- }
- #endif /* NOWORM */
|