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