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