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