1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64: #include <sys/cdefs.h>
65: #ifndef lint
66: __RCSID("$NetBSD: hack.worm.c,v 1.5 2003/04/02 18:36:41 jsm Exp $");
67: #endif
68:
69: #include <stdlib.h>
70: #include "hack.h"
71: #include "extern.h"
72: #ifndef NOWORM
73: #include "def.wseg.h"
74:
75: struct wseg *wsegs[32];
76: struct wseg *wheads[32];
77: long wgrowtime[32];
78:
79: int
80: getwn(mtmp)
81: struct monst *mtmp;
82: {
83: int tmp;
84: for (tmp = 1; tmp < 32; tmp++)
85: if (!wsegs[tmp]) {
86: mtmp->wormno = tmp;
87: return (1);
88: }
89: return (0);
90: }
91:
92:
93: void
94: initworm(mtmp)
95: struct monst *mtmp;
96: {
97: struct wseg *wtmp;
98: int tmp = mtmp->wormno;
99: if (!tmp)
100: return;
101: wheads[tmp] = wsegs[tmp] = wtmp = newseg();
102: wgrowtime[tmp] = 0;
103: wtmp->wx = mtmp->mx;
104: wtmp->wy = mtmp->my;
105:
106: wtmp->nseg = 0;
107: }
108:
109: void
110: worm_move(mtmp)
111: struct monst *mtmp;
112: {
113: struct wseg *wtmp, *whd = NULL;
114: int tmp = mtmp->wormno;
115: wtmp = newseg();
116: wtmp->wx = mtmp->mx;
117: wtmp->wy = mtmp->my;
118: wtmp->nseg = 0;
119:
120: (whd = wheads[tmp])->nseg = wtmp;
121: wheads[tmp] = wtmp;
122: if (cansee(whd->wx, whd->wy)) {
123: unpmon(mtmp);
124: atl(whd->wx, whd->wy, '~');
125: whd->wdispl = 1;
126: } else
127: whd->wdispl = 0;
128: if (wgrowtime[tmp] <= moves) {
129: if (!wgrowtime[tmp])
130: wgrowtime[tmp] = moves + rnd(5);
131: else
132: wgrowtime[tmp] += 2 + rnd(15);
133: mtmp->mhpmax += 3;
134: mtmp->mhp += 3;
135: return;
136: }
137: whd = wsegs[tmp];
138: wsegs[tmp] = whd->nseg;
139: remseg(whd);
140: }
141:
142: void
143: worm_nomove(mtmp)
144: struct monst *mtmp;
145: {
146: int tmp;
147: struct wseg *wtmp;
148: tmp = mtmp->wormno;
149: wtmp = wsegs[tmp];
150: if (wtmp == wheads[tmp])
151: return;
152: if (wtmp == 0 || wtmp->nseg == 0)
153: panic("worm_nomove?");
154: wsegs[tmp] = wtmp->nseg;
155: remseg(wtmp);
156: mtmp->mhp -= 3;
157: }
158:
159: void
160: wormdead(mtmp)
161: struct monst *mtmp;
162: {
163: int tmp = mtmp->wormno;
164: struct wseg *wtmp, *wtmp2;
165: if (!tmp)
166: return;
167: mtmp->wormno = 0;
168: for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2) {
169: wtmp2 = wtmp->nseg;
170: remseg(wtmp);
171: }
172: wsegs[tmp] = 0;
173: }
174:
175: void
176: wormhit(mtmp)
177: struct monst *mtmp;
178: {
179: int tmp = mtmp->wormno;
180: struct wseg *wtmp;
181: if (!tmp)
182: return;
183: for (wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg)
184: (void) hitu(mtmp, 1);
185: }
186:
187: void
188: wormsee(tmp)
189: unsigned tmp;
190: {
191: struct wseg *wtmp = wsegs[tmp];
192: if (!wtmp)
193: panic("wormsee: wtmp==0");
194: for (; wtmp->nseg; wtmp = wtmp->nseg)
195: if (!cansee(wtmp->wx, wtmp->wy) && wtmp->wdispl) {
196: newsym(wtmp->wx, wtmp->wy);
197: wtmp->wdispl = 0;
198: }
199: }
200:
201: void
202: pwseg(wtmp)
203: struct wseg *wtmp;
204: {
205: if (!wtmp->wdispl) {
206: atl(wtmp->wx, wtmp->wy, '~');
207: wtmp->wdispl = 1;
208: }
209: }
210:
211: void
212: cutworm(mtmp, x, y, weptyp)
213: struct monst *mtmp;
214: xchar x, y;
215: uchar weptyp;
216: {
217: struct wseg *wtmp, *wtmp2;
218: struct monst *mtmp2;
219: int tmp, tmp2;
220: if (mtmp->mx == x && mtmp->my == y)
221: return;
222:
223:
224: tmp = rnd(20);
225: if (weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD ||
226: weptyp == AXE)
227: tmp += 5;
228: if (tmp < 12)
229: return;
230:
231:
232: tmp = mtmp->wormno;
233: wtmp = wsegs[tmp];
234: if (wtmp->wx == x && wtmp->wy == y) {
235: wsegs[tmp] = wtmp->nseg;
236: remseg(wtmp);
237: return;
238: }
239:
240: mtmp2 = newmonst(0);
241: *mtmp2 = *mtmp;
242: mtmp2->mxlth = mtmp2->mnamelth = 0;
243:
244:
245: if (rn2(3) || !getwn(mtmp2)) {
246: monfree(mtmp2);
247: tmp2 = 0;
248: } else {
249: tmp2 = mtmp2->wormno;
250: wsegs[tmp2] = wsegs[tmp];
251: wgrowtime[tmp2] = 0;
252: }
253: do {
254: if (wtmp->nseg->wx == x && wtmp->nseg->wy == y) {
255: if (tmp2)
256: wheads[tmp2] = wtmp;
257: wsegs[tmp] = wtmp->nseg->nseg;
258: remseg(wtmp->nseg);
259: wtmp->nseg = 0;
260: if (tmp2) {
261: pline("You cut the worm in half.");
262: mtmp2->mhpmax = mtmp2->mhp =
263: d(mtmp2->data->mlevel, 8);
264: mtmp2->mx = wtmp->wx;
265: mtmp2->my = wtmp->wy;
266: mtmp2->nmon = fmon;
267: fmon = mtmp2;
268: pmon(mtmp2);
269: } else {
270: pline("You cut off part of the worm's tail.");
271: remseg(wtmp);
272: }
273: mtmp->mhp /= 2;
274: return;
275: }
276: wtmp2 = wtmp->nseg;
277: if (!tmp2)
278: remseg(wtmp);
279: wtmp = wtmp2;
280: } while (wtmp->nseg);
281: panic("Cannot find worm segment");
282: }
283:
284: void
285: remseg(wtmp)
286: struct wseg *wtmp;
287: {
288: if (wtmp->wdispl)
289: newsym(wtmp->wx, wtmp->wy);
290: free((char *) wtmp);
291: }
292: #endif