summaryrefslogtreecommitdiffstats
path: root/hack/hack.worm.c
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
committercgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
commit77e3814f0c0e3dea4d0032e25666f77e6f83bfff (patch)
tree7eddfcbf3dd12089e71dc3fafb0a106c5c5766c7 /hack/hack.worm.c
parente81d63576b2e46ab90da7d75fa155ea57ee4d32e (diff)
downloadbsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.gz
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.zst
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.zip
initial import of 386bsd-0.1 sources
Diffstat (limited to 'hack/hack.worm.c')
-rw-r--r--hack/hack.worm.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/hack/hack.worm.c b/hack/hack.worm.c
new file mode 100644
index 00000000..ba3505d1
--- /dev/null
+++ b/hack/hack.worm.c
@@ -0,0 +1,183 @@
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* hack.worm.c - version 1.0.2 */
+
+#include "hack.h"
+#ifndef NOWORM
+#include "def.wseg.h"
+
+struct wseg *wsegs[32]; /* linked list, tail first */
+struct wseg *wheads[32];
+long wgrowtime[32];
+
+getwn(mtmp) struct monst *mtmp; {
+register 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 */
+initworm(mtmp) struct monst *mtmp; {
+register struct wseg *wtmp;
+register 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;
+}
+
+worm_move(mtmp) struct monst *mtmp; {
+register struct wseg *wtmp, *whd;
+register 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);
+}
+
+worm_nomove(mtmp) register struct monst *mtmp; {
+register tmp;
+register 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 ! */
+}
+
+wormdead(mtmp) register struct monst *mtmp; {
+register tmp = mtmp->wormno;
+register 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;
+}
+
+wormhit(mtmp) register struct monst *mtmp; {
+register tmp = mtmp->wormno;
+register struct wseg *wtmp;
+ if(!tmp) return; /* worm without tail */
+ for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
+ (void) hitu(mtmp,1);
+}
+
+wormsee(tmp) register unsigned tmp; {
+register 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;
+ }
+}
+
+pwseg(wtmp) register struct wseg *wtmp; {
+ if(!wtmp->wdispl){
+ atl(wtmp->wx, wtmp->wy, '~');
+ wtmp->wdispl = 1;
+ }
+}
+
+cutworm(mtmp,x,y,weptyp)
+register struct monst *mtmp;
+register xchar x,y;
+register uchar weptyp; /* uwep->otyp or 0 */
+{
+ register struct wseg *wtmp, *wtmp2;
+ register struct monst *mtmp2;
+ register 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");
+}
+
+remseg(wtmp) register struct wseg *wtmp; {
+ if(wtmp->wdispl)
+ newsym(wtmp->wx, wtmp->wy);
+ free((char *) wtmp);
+}
+#endif NOWORM