Source:NetHack 3.0.0/worm.c

Below is the full text to worm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/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	3.0	88/11/11 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   #ifdef WORM 8.   #include "wseg.h"  9. 10.  struct wseg *wsegs[32] = DUMMY, *wheads[32] = DUMMY, *m_atseg = 0; 11.  long wgrowtime[32] = DUMMY; 12.   13.   int 14.  getwn(mtmp) 15.  struct monst *mtmp; 16.  {  17.   	register int tmp; 18.   19.   	for(tmp = 1; tmp < 32; tmp++) 20.  	    if(!wsegs[tmp]) { 21.  		mtmp->wormno = tmp; 22.  		return(1); 23.  	    }  24.   	return(0);	/* level infested with worms */ 25.  }  26.    27.   /* called to initialize a worm unless cut in half */ 28.  void 29.  initworm(mtmp) 30.  struct monst *mtmp; 31.  {  32.   	register struct wseg *wtmp; 33.  	register int tmp = mtmp->wormno; 34.   35.   	if(!tmp) return; 36.  	wheads[tmp] = wsegs[tmp] = wtmp = newseg; 37.  	wgrowtime[tmp] = 0; 38.  	wtmp->wx = mtmp->mx; 39.  	wtmp->wy = mtmp->my; 40.  /*	wtmp->wdispl = 0; */ 41.  	wtmp->nseg = 0; 42.  }  43.    44.   static void 45.  remseg(mtmp,wtmp) 46.  struct monst *mtmp; 47.  register struct wseg *wtmp; 48.  {  49.   	if (mtmp->mx != wtmp->wx || mtmp->my != wtmp->wy) 50.  		levl[wtmp->wx][wtmp->wy].mmask = 0; 51.  	if(wtmp->wdispl) newsym(wtmp->wx, wtmp->wy); 52.  	free((genericptr_t) wtmp); 53.  }  54.    55.   void 56.  worm_move(mtmp) 57.  struct monst *mtmp; 58.  {  59.   	register struct wseg *wtmp, *whd; 60.  	register int tmp = mtmp->wormno; 61.   62.   	wtmp = newseg; 63.  	wtmp->wx = mtmp->mx; 64.  	wtmp->wy = mtmp->my; 65.  	wtmp->nseg = 0; 66.  /*	wtmp->wdispl = 0; */ 67.  	(whd = wheads[tmp])->nseg = wtmp; 68.  	wheads[tmp] = wtmp; 69.  	if(cansee(whd->wx,whd->wy)){ 70.  		unpmon(mtmp); 71.  		atl(whd->wx, whd->wy, S_WORM_TAIL); 72.  		whd->wdispl = 1; 73.  	} else	whd->wdispl = 0; 74.  	if(wgrowtime[tmp] <= moves) { 75.  		if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5); 76.  		else wgrowtime[tmp] += 2+rnd(15); 77.  		mtmp->mhp += 3; 78.  		if (mtmp->mhp > MHPMAX) mtmp->mhp = MHPMAX; 79.  		if (mtmp->mhp > mtmp->mhpmax) mtmp->mhpmax = mtmp->mhp; 80.  		return; 81.  	}  82.   	whd = wsegs[tmp]; 83.  	wsegs[tmp] = whd->nseg; 84.  	remseg(mtmp, whd); 85.  }  86.    87.   void 88.  worm_nomove(mtmp) 89.  register struct monst *mtmp; 90.  {  91.   	register int tmp; 92.  	register struct wseg *wtmp; 93.   94.   	tmp = mtmp->wormno; 95.  	wtmp = wsegs[tmp]; 96.  	if(wtmp == wheads[tmp]) return; 97.  	if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?"); 98.  	wsegs[tmp] = wtmp->nseg; 99.  	remseg(mtmp, wtmp); 100. 	if (mtmp->mhp > 3) mtmp->mhp -= 3;	/* mhpmax not changed ! */ 101.  	else mtmp->mhp = 1; 102. }  103.   104.  void 105. wormdead(mtmp) 106. register struct monst *mtmp; 107. {  108.  	register int tmp = mtmp->wormno; 109. 	register struct wseg *wtmp, *wtmp2; 110.  111.  	if(!tmp) return; 112. 	mtmp->wormno = 0; 113. 	for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) { 114. 		wtmp2 = wtmp->nseg; 115. 		remseg(mtmp, wtmp); 116. 	}  117.  	wsegs[tmp] = 0; 118. }  119.   120.  void 121. wormhit(mtmp) 122. register struct monst *mtmp; 123. {  124.  	register int tmp = mtmp->wormno; 125. 	register struct wseg *wtmp; 126.  127.  	if(!tmp) return;	/* worm without tail */ 128. 	for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg) 129. 		if (dist(wtmp->wx, wtmp->wy) < 3) (void) mattacku(mtmp); 130. }  131.   132.  void 133. wormsee(tmp) 134. register unsigned int tmp; 135. {  136.  	register struct wseg *wtmp = wsegs[tmp]; 137.  138.  	if(!wtmp) panic("wormsee: wtmp==0"); 139.  140.  	for(wtmp->nseg; wtmp = wtmp->nseg) 141. 		if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl) { 142. 			newsym(wtmp->wx, wtmp->wy); 143. 			wtmp->wdispl = 0; 144. 		}  145.  }  146.   147.  void 148. cutworm(mtmp, x, y, weptyp) 149. register struct monst *mtmp; 150. register xchar x,y; 151. register unsigned weptyp;		/* uwep->otyp or 0 */ 152. {  153.  	register struct wseg *wtmp, *wtmp2; 154. 	register struct monst *mtmp2; 155. 	register int tmp, tmp2; 156.  157.  	if(mtmp->mx == x && mtmp->my == y) return;	/* hit headon */ 158.  159.  	/* cutting goes best with axe or sword */ 160. 	tmp = rnd(20); 161. 	if(weptyp >= SHORT_SWORD && weptyp <= KATANA ||  162.  	   weptyp == AXE) 163. 		tmp += 5; 164.  165.  	if(tmp < 12) return; 166.  167.  	/* if tail then worm just loses a tail segment */ 168. 	tmp = mtmp->wormno; 169. 	wtmp = wsegs[tmp]; 170. 	if(wtmp->wx == x && wtmp->wy == y){ 171. 		wsegs[tmp] = wtmp->nseg; 172. 		remseg(mtmp, wtmp); 173. 		return; 174. 	}  175.   176.  	/* cut the worm in two halves */ 177. 	mtmp2 = newmonst(0); 178. 	*mtmp2 = *mtmp; 179. 	mtmp2->mxlth = mtmp2->mnamelth = 0; 180.  181.  	/* sometimes the tail end dies */ 182. 	if(rn2(3) || !getwn(mtmp2)){ 183. 		monfree(mtmp2); 184. 		levl[mtmp2->mx][mtmp2->my].mmask = 1; 185. 			/* since mtmp is still on that spot */ 186. 		tmp2 = 0; 187. 	} else { 188. 		tmp2 = mtmp2->wormno; 189. 		wsegs[tmp2] = wsegs[tmp]; 190. 		wgrowtime[tmp2] = 0; 191. 	}  192.  	do { 193. 	    if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){ 194. 		if(tmp2) wheads[tmp2] = wtmp; 195. 		wsegs[tmp] = wtmp->nseg->nseg; 196. 		remseg(mtmp, wtmp->nseg); 197. 		wtmp->nseg = 0; 198. 		if(tmp2) { 199. 		    You("cut the worm in half."); 200. 		/* devalue the monster level of both halves of the worm */ 201. 		    mtmp->m_lev = (mtmp->m_lev <= 2) ? 2 : mtmp->m_lev - 2; 202. 		    mtmp2->m_lev = mtmp->m_lev; 203. 		/* calculate the mhp on the new (lower) monster level */ 204. 		    mtmp2->mhpmax = mtmp2->mhp = d((int)mtmp2->m_lev, 8); 205. 		    mtmp2->mx = wtmp->wx; 206. 		    mtmp2->my = wtmp->wy; 207. 		    levl[mtmp2->mx][mtmp2->my].mmask = 1; 208. 		    mtmp2->nmon = fmon; 209. 		    fmon = mtmp2; 210. 		    mtmp2->mdispl = 0; 211. 		    pmon(mtmp2); 212. 		} else { 213. 			You("cut off part of the worm's tail."); 214. 			remseg(mtmp, wtmp); 215. 		}  216.  		mtmp->mhp /= 2; 217. 		return; 218. 	    }  219.  	    wtmp2 = wtmp->nseg; 220. 	    if(!tmp2) remseg(mtmp, wtmp); 221. 	    wtmp = wtmp2; 222. 	} while(wtmp->nseg); 223. 	panic("Cannot find worm segment"); 224. }  225.   226.  #endif /* WORM /**/