Home | History | Annotate | Line # | Download | only in hack
hack.worm.c revision 1.2
      1  1.2  mycroft /*
      2  1.2  mycroft  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
      3  1.2  mycroft  */
      4  1.2  mycroft 
      5  1.2  mycroft #ifndef lint
      6  1.2  mycroft static char rcsid[] = "$Id: hack.worm.c,v 1.2 1993/08/02 17:19:40 mycroft Exp $";
      7  1.2  mycroft #endif /* not lint */
      8  1.1      cgd 
      9  1.1      cgd #include "hack.h"
     10  1.1      cgd #ifndef NOWORM
     11  1.1      cgd #include "def.wseg.h"
     12  1.1      cgd 
     13  1.1      cgd struct wseg *wsegs[32];	/* linked list, tail first */
     14  1.1      cgd struct wseg *wheads[32];
     15  1.1      cgd long wgrowtime[32];
     16  1.1      cgd 
     17  1.1      cgd getwn(mtmp) struct monst *mtmp; {
     18  1.1      cgd register tmp;
     19  1.1      cgd 	for(tmp=1; tmp<32; tmp++) if(!wsegs[tmp]) {
     20  1.1      cgd 		mtmp->wormno = tmp;
     21  1.1      cgd 		return(1);
     22  1.1      cgd 	}
     23  1.1      cgd 	return(0);	/* level infested with worms */
     24  1.1      cgd }
     25  1.1      cgd 
     26  1.1      cgd /* called to initialize a worm unless cut in half */
     27  1.1      cgd initworm(mtmp) struct monst *mtmp; {
     28  1.1      cgd register struct wseg *wtmp;
     29  1.1      cgd register tmp = mtmp->wormno;
     30  1.1      cgd 	if(!tmp) return;
     31  1.1      cgd 	wheads[tmp] = wsegs[tmp] = wtmp = newseg();
     32  1.1      cgd 	wgrowtime[tmp] = 0;
     33  1.1      cgd 	wtmp->wx = mtmp->mx;
     34  1.1      cgd 	wtmp->wy = mtmp->my;
     35  1.1      cgd /*	wtmp->wdispl = 0; */
     36  1.1      cgd 	wtmp->nseg = 0;
     37  1.1      cgd }
     38  1.1      cgd 
     39  1.1      cgd worm_move(mtmp) struct monst *mtmp; {
     40  1.1      cgd register struct wseg *wtmp, *whd;
     41  1.1      cgd register tmp = mtmp->wormno;
     42  1.1      cgd 	wtmp = newseg();
     43  1.1      cgd 	wtmp->wx = mtmp->mx;
     44  1.1      cgd 	wtmp->wy = mtmp->my;
     45  1.1      cgd 	wtmp->nseg = 0;
     46  1.1      cgd /*	wtmp->wdispl = 0; */
     47  1.1      cgd 	(whd = wheads[tmp])->nseg = wtmp;
     48  1.1      cgd 	wheads[tmp] = wtmp;
     49  1.1      cgd 	if(cansee(whd->wx,whd->wy)){
     50  1.1      cgd 		unpmon(mtmp);
     51  1.1      cgd 		atl(whd->wx, whd->wy, '~');
     52  1.1      cgd 		whd->wdispl = 1;
     53  1.1      cgd 	} else	whd->wdispl = 0;
     54  1.1      cgd 	if(wgrowtime[tmp] <= moves) {
     55  1.1      cgd 		if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5);
     56  1.1      cgd 		else wgrowtime[tmp] += 2+rnd(15);
     57  1.1      cgd 		mtmp->mhpmax += 3;
     58  1.1      cgd 		mtmp->mhp += 3;
     59  1.1      cgd 		return;
     60  1.1      cgd 	}
     61  1.1      cgd 	whd = wsegs[tmp];
     62  1.1      cgd 	wsegs[tmp] = whd->nseg;
     63  1.1      cgd 	remseg(whd);
     64  1.1      cgd }
     65  1.1      cgd 
     66  1.1      cgd worm_nomove(mtmp) register struct monst *mtmp; {
     67  1.1      cgd register tmp;
     68  1.1      cgd register struct wseg *wtmp;
     69  1.1      cgd 	tmp = mtmp->wormno;
     70  1.1      cgd 	wtmp = wsegs[tmp];
     71  1.1      cgd 	if(wtmp == wheads[tmp]) return;
     72  1.1      cgd 	if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?");
     73  1.1      cgd 	wsegs[tmp] = wtmp->nseg;
     74  1.1      cgd 	remseg(wtmp);
     75  1.1      cgd 	mtmp->mhp -= 3;	/* mhpmax not changed ! */
     76  1.1      cgd }
     77  1.1      cgd 
     78  1.1      cgd wormdead(mtmp) register struct monst *mtmp; {
     79  1.1      cgd register tmp = mtmp->wormno;
     80  1.1      cgd register struct wseg *wtmp, *wtmp2;
     81  1.1      cgd 	if(!tmp) return;
     82  1.1      cgd 	mtmp->wormno = 0;
     83  1.1      cgd 	for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){
     84  1.1      cgd 		wtmp2 = wtmp->nseg;
     85  1.1      cgd 		remseg(wtmp);
     86  1.1      cgd 	}
     87  1.1      cgd 	wsegs[tmp] = 0;
     88  1.1      cgd }
     89  1.1      cgd 
     90  1.1      cgd wormhit(mtmp) register struct monst *mtmp; {
     91  1.1      cgd register tmp = mtmp->wormno;
     92  1.1      cgd register struct wseg *wtmp;
     93  1.1      cgd 	if(!tmp) return;	/* worm without tail */
     94  1.1      cgd 	for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
     95  1.1      cgd 		(void) hitu(mtmp,1);
     96  1.1      cgd }
     97  1.1      cgd 
     98  1.1      cgd wormsee(tmp) register unsigned tmp; {
     99  1.1      cgd register struct wseg *wtmp = wsegs[tmp];
    100  1.1      cgd 	if(!wtmp) panic("wormsee: wtmp==0");
    101  1.1      cgd 	for(; wtmp->nseg; wtmp = wtmp->nseg)
    102  1.1      cgd 		if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl){
    103  1.1      cgd 			newsym(wtmp->wx, wtmp->wy);
    104  1.1      cgd 			wtmp->wdispl = 0;
    105  1.1      cgd 		}
    106  1.1      cgd }
    107  1.1      cgd 
    108  1.1      cgd pwseg(wtmp) register struct wseg *wtmp; {
    109  1.1      cgd 	if(!wtmp->wdispl){
    110  1.1      cgd 		atl(wtmp->wx, wtmp->wy, '~');
    111  1.1      cgd 		wtmp->wdispl = 1;
    112  1.1      cgd 	}
    113  1.1      cgd }
    114  1.1      cgd 
    115  1.1      cgd cutworm(mtmp,x,y,weptyp)
    116  1.1      cgd register struct monst *mtmp;
    117  1.1      cgd register xchar x,y;
    118  1.1      cgd register uchar weptyp;		/* uwep->otyp or 0 */
    119  1.1      cgd {
    120  1.1      cgd 	register struct wseg *wtmp, *wtmp2;
    121  1.1      cgd 	register struct monst *mtmp2;
    122  1.1      cgd 	register tmp,tmp2;
    123  1.1      cgd 	if(mtmp->mx == x && mtmp->my == y) return;	/* hit headon */
    124  1.1      cgd 
    125  1.1      cgd 	/* cutting goes best with axe or sword */
    126  1.1      cgd 	tmp = rnd(20);
    127  1.1      cgd 	if(weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
    128  1.1      cgd 		weptyp == AXE) tmp += 5;
    129  1.1      cgd 	if(tmp < 12) return;
    130  1.1      cgd 
    131  1.1      cgd 	/* if tail then worm just loses a tail segment */
    132  1.1      cgd 	tmp = mtmp->wormno;
    133  1.1      cgd 	wtmp = wsegs[tmp];
    134  1.1      cgd 	if(wtmp->wx == x && wtmp->wy == y){
    135  1.1      cgd 		wsegs[tmp] = wtmp->nseg;
    136  1.1      cgd 		remseg(wtmp);
    137  1.1      cgd 		return;
    138  1.1      cgd 	}
    139  1.1      cgd 
    140  1.1      cgd 	/* cut the worm in two halves */
    141  1.1      cgd 	mtmp2 = newmonst(0);
    142  1.1      cgd 	*mtmp2 = *mtmp;
    143  1.1      cgd 	mtmp2->mxlth = mtmp2->mnamelth = 0;
    144  1.1      cgd 
    145  1.1      cgd 	/* sometimes the tail end dies */
    146  1.1      cgd 	if(rn2(3) || !getwn(mtmp2)){
    147  1.1      cgd 		monfree(mtmp2);
    148  1.1      cgd 		tmp2 = 0;
    149  1.1      cgd 	} else {
    150  1.1      cgd 		tmp2 = mtmp2->wormno;
    151  1.1      cgd 		wsegs[tmp2] = wsegs[tmp];
    152  1.1      cgd 		wgrowtime[tmp2] = 0;
    153  1.1      cgd 	}
    154  1.1      cgd 	do {
    155  1.1      cgd 		if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){
    156  1.1      cgd 			if(tmp2) wheads[tmp2] = wtmp;
    157  1.1      cgd 			wsegs[tmp] = wtmp->nseg->nseg;
    158  1.1      cgd 			remseg(wtmp->nseg);
    159  1.1      cgd 			wtmp->nseg = 0;
    160  1.1      cgd 			if(tmp2){
    161  1.1      cgd 				pline("You cut the worm in half.");
    162  1.1      cgd 				mtmp2->mhpmax = mtmp2->mhp =
    163  1.1      cgd 					d(mtmp2->data->mlevel, 8);
    164  1.1      cgd 				mtmp2->mx = wtmp->wx;
    165  1.1      cgd 				mtmp2->my = wtmp->wy;
    166  1.1      cgd 				mtmp2->nmon = fmon;
    167  1.1      cgd 				fmon = mtmp2;
    168  1.1      cgd 				pmon(mtmp2);
    169  1.1      cgd 			} else {
    170  1.1      cgd 				pline("You cut off part of the worm's tail.");
    171  1.1      cgd 				remseg(wtmp);
    172  1.1      cgd 			}
    173  1.1      cgd 			mtmp->mhp /= 2;
    174  1.1      cgd 			return;
    175  1.1      cgd 		}
    176  1.1      cgd 		wtmp2 = wtmp->nseg;
    177  1.1      cgd 		if(!tmp2) remseg(wtmp);
    178  1.1      cgd 		wtmp = wtmp2;
    179  1.1      cgd 	} while(wtmp->nseg);
    180  1.1      cgd 	panic("Cannot find worm segment");
    181  1.1      cgd }
    182  1.1      cgd 
    183  1.1      cgd remseg(wtmp) register struct wseg *wtmp; {
    184  1.1      cgd 	if(wtmp->wdispl)
    185  1.1      cgd 		newsym(wtmp->wx, wtmp->wy);
    186  1.1      cgd 	free((char *) wtmp);
    187  1.1      cgd }
    188  1.1      cgd #endif NOWORM
    189