]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - games/hack/hack.worm.c
This commit was generated by cvs2svn to compensate for changes in r66494,
[FreeBSD/FreeBSD.git] / games / hack / hack.worm.c
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.worm.c - version 1.0.2 */
3 /* $FreeBSD$ */
4
5 #include "hack.h"
6 #ifndef NOWORM
7 #include "def.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 int 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 struct wseg *wtmp;
25 int 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 struct wseg *wtmp, *whd;
37 int 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) struct monst *mtmp; {
63 int tmp;
64 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) struct monst *mtmp; {
75 int tmp = mtmp->wormno;
76 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) struct monst *mtmp; {
87 int tmp = mtmp->wormno;
88 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) unsigned tmp; {
95 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) 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 struct monst *mtmp;
113 xchar x,y;
114 uchar weptyp;           /* uwep->otyp or 0 */
115 {
116         struct wseg *wtmp, *wtmp2;
117         struct monst *mtmp2;
118         int 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 == AXE) tmp += 5;
125         if(tmp < 12) return;
126
127         /* if tail then worm just loses a tail segment */
128         tmp = mtmp->wormno;
129         wtmp = wsegs[tmp];
130         if(wtmp->wx == x && wtmp->wy == y){
131                 wsegs[tmp] = wtmp->nseg;
132                 remseg(wtmp);
133                 return;
134         }
135
136         /* cut the worm in two halves */
137         mtmp2 = newmonst(0);
138         *mtmp2 = *mtmp;
139         mtmp2->mxlth = mtmp2->mnamelth = 0;
140
141         /* sometimes the tail end dies */
142         if(rn2(3) || !getwn(mtmp2)){
143                 monfree(mtmp2);
144                 tmp2 = 0;
145         } else {
146                 tmp2 = mtmp2->wormno;
147                 wsegs[tmp2] = wsegs[tmp];
148                 wgrowtime[tmp2] = 0;
149         }
150         do {
151                 if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){
152                         if(tmp2) wheads[tmp2] = wtmp;
153                         wsegs[tmp] = wtmp->nseg->nseg;
154                         remseg(wtmp->nseg);
155                         wtmp->nseg = 0;
156                         if(tmp2){
157                                 pline("You cut the worm in half.");
158                                 mtmp2->mhpmax = mtmp2->mhp =
159                                         d(mtmp2->data->mlevel, 8);
160                                 mtmp2->mx = wtmp->wx;
161                                 mtmp2->my = wtmp->wy;
162                                 mtmp2->nmon = fmon;
163                                 fmon = mtmp2;
164                                 pmon(mtmp2);
165                         } else {
166                                 pline("You cut off part of the worm's tail.");
167                                 remseg(wtmp);
168                         }
169                         mtmp->mhp /= 2;
170                         return;
171                 }
172                 wtmp2 = wtmp->nseg;
173                 if(!tmp2) remseg(wtmp);
174                 wtmp = wtmp2;
175         } while(wtmp->nseg);
176         panic("Cannot find worm segment");
177 }
178
179 remseg(wtmp) struct wseg *wtmp; {
180         if(wtmp->wdispl)
181                 newsym(wtmp->wx, wtmp->wy);
182         free((char *) wtmp);
183 }
184 #endif NOWORM