Source:NetHack 3.0.0/worm.c

From NetHackWiki
Jump to navigation Jump to search

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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 /**/