Source:NetHack 2.2a/worm.c

Below is the full text to worm.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/worm.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

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