Source:Hack 1.0/hack.worm.c

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

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

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