Source:NetHack 1.3d/worm.c

From NetHackWiki
Jump to: navigation, search

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

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)worm.c	1.3	87/07/14
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 /**/