1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.worm.c - version 1.0.2 */
3 /* $FreeBSD: src/games/hack/hack.worm.c,v 1.4 1999/11/16 10:26:38 marcel Exp $ */
8 struct wseg
*wsegs
[32]; /* linked list, tail first */
9 struct wseg
*wheads
[32];
12 static void remseg(struct wseg
*);
15 getwn(struct monst
*mtmp
)
19 for (tmp
= 1; tmp
< 32; tmp
++)
24 return (0); /* level infested with worms */
27 /* called to initialize a worm unless cut in half */
29 initworm(struct monst
*mtmp
)
32 int tmp
= mtmp
->wormno
;
36 wheads
[tmp
] = wsegs
[tmp
] = wtmp
= newseg();
44 worm_move(struct monst
*mtmp
)
46 struct wseg
*wtmp
, *whd
;
47 int tmp
= mtmp
->wormno
;
53 (whd
= wheads
[tmp
])->nseg
= wtmp
;
55 if (cansee(whd
->wx
, whd
->wy
)) {
57 atl(whd
->wx
, whd
->wy
, '~');
61 if (wgrowtime
[tmp
] <= moves
) {
63 wgrowtime
[tmp
] = moves
+ rnd(5);
65 wgrowtime
[tmp
] += 2 + rnd(15);
71 wsegs
[tmp
] = whd
->nseg
;
76 worm_nomove(struct monst
*mtmp
)
83 if (wtmp
== wheads
[tmp
])
85 if (wtmp
== NULL
|| wtmp
->nseg
== 0)
86 panic("worm_nomove?");
87 wsegs
[tmp
] = wtmp
->nseg
;
89 mtmp
->mhp
-= 3; /* mhpmax not changed ! */
93 wormdead(struct monst
*mtmp
)
95 int tmp
= mtmp
->wormno
;
96 struct wseg
*wtmp
, *wtmp2
;
101 for (wtmp
= wsegs
[tmp
]; wtmp
; wtmp
= wtmp2
) {
109 wormhit(struct monst
*mtmp
)
111 int tmp
= mtmp
->wormno
;
114 if (!tmp
) /* worm without tail */
116 for (wtmp
= wsegs
[tmp
]; wtmp
; wtmp
= wtmp
->nseg
)
121 wormsee(unsigned int tmp
)
123 struct wseg
*wtmp
= wsegs
[tmp
];
126 panic("wormsee: wtmp==0");
127 for (; wtmp
->nseg
; wtmp
= wtmp
->nseg
)
128 if (!cansee(wtmp
->wx
, wtmp
->wy
) && wtmp
->wdispl
) {
129 newsym(wtmp
->wx
, wtmp
->wy
);
135 pwseg(struct wseg
*wtmp
)
138 atl(wtmp
->wx
, wtmp
->wy
, '~');
143 /* weptyp: uwep->otyp or 0 */
145 cutworm(struct monst
*mtmp
, xchar x
, xchar y
, uchar weptyp
)
147 struct wseg
*wtmp
, *wtmp2
;
151 if (mtmp
->mx
== x
&& mtmp
->my
== y
) /* hit headon */
154 /* cutting goes best with axe or sword */
156 if (weptyp
== LONG_SWORD
|| weptyp
== TWO_HANDED_SWORD
||
162 /* if tail then worm just loses a tail segment */
165 if (wtmp
->wx
== x
&& wtmp
->wy
== y
) {
166 wsegs
[tmp
] = wtmp
->nseg
;
171 /* cut the worm in two halves */
174 mtmp2
->mxlth
= mtmp2
->mnamelth
= 0;
176 /* sometimes the tail end dies */
177 if (rn2(3) || !getwn(mtmp2
)) {
181 tmp2
= mtmp2
->wormno
;
182 wsegs
[tmp2
] = wsegs
[tmp
];
186 if (wtmp
->nseg
->wx
== x
&& wtmp
->nseg
->wy
== y
) {
189 wsegs
[tmp
] = wtmp
->nseg
->nseg
;
193 pline("You cut the worm in half.");
194 mtmp2
->mhpmax
= mtmp2
->mhp
=
195 d(mtmp2
->data
->mlevel
, 8);
196 mtmp2
->mx
= wtmp
->wx
;
197 mtmp2
->my
= wtmp
->wy
;
202 pline("You cut off part of the worm's tail.");
212 } while (wtmp
->nseg
);
213 panic("Cannot find worm segment");
217 remseg(struct wseg
*wtmp
)
220 newsym(wtmp
->wx
, wtmp
->wy
);