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 $ */
4 /* $DragonFly: src/games/hack/hack.worm.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */
9 struct wseg
*wsegs
[32]; /* linked list, tail first */
10 struct wseg
*wheads
[32];
13 static void remseg(struct wseg
*);
16 getwn(struct monst
*mtmp
)
20 for (tmp
= 1; tmp
< 32; tmp
++)
25 return (0); /* level infested with worms */
28 /* called to initialize a worm unless cut in half */
30 initworm(struct monst
*mtmp
)
33 int tmp
= mtmp
->wormno
;
37 wheads
[tmp
] = wsegs
[tmp
] = wtmp
= newseg();
45 worm_move(struct monst
*mtmp
)
47 struct wseg
*wtmp
, *whd
;
48 int tmp
= mtmp
->wormno
;
54 (whd
= wheads
[tmp
])->nseg
= wtmp
;
56 if (cansee(whd
->wx
, whd
->wy
)) {
58 atl(whd
->wx
, whd
->wy
, '~');
62 if (wgrowtime
[tmp
] <= moves
) {
64 wgrowtime
[tmp
] = moves
+ rnd(5);
66 wgrowtime
[tmp
] += 2 + rnd(15);
72 wsegs
[tmp
] = whd
->nseg
;
77 worm_nomove(struct monst
*mtmp
)
84 if (wtmp
== wheads
[tmp
])
86 if (wtmp
== 0 || wtmp
->nseg
== 0)
87 panic("worm_nomove?");
88 wsegs
[tmp
] = wtmp
->nseg
;
90 mtmp
->mhp
-= 3; /* mhpmax not changed ! */
94 wormdead(struct monst
*mtmp
)
96 int tmp
= mtmp
->wormno
;
97 struct wseg
*wtmp
, *wtmp2
;
102 for (wtmp
= wsegs
[tmp
]; wtmp
; wtmp
= wtmp2
) {
110 wormhit(struct monst
*mtmp
)
112 int tmp
= mtmp
->wormno
;
115 if (!tmp
) /* worm without tail */
117 for (wtmp
= wsegs
[tmp
]; wtmp
; wtmp
= wtmp
->nseg
)
122 wormsee(unsigned int tmp
)
124 struct wseg
*wtmp
= wsegs
[tmp
];
127 panic("wormsee: wtmp==0");
128 for (; wtmp
->nseg
; wtmp
= wtmp
->nseg
)
129 if (!cansee(wtmp
->wx
, wtmp
->wy
) && wtmp
->wdispl
) {
130 newsym(wtmp
->wx
, wtmp
->wy
);
136 pwseg(struct wseg
*wtmp
)
139 atl(wtmp
->wx
, wtmp
->wy
, '~');
144 /* weptyp: uwep->otyp or 0 */
146 cutworm(struct monst
*mtmp
, xchar x
, xchar y
, uchar weptyp
)
148 struct wseg
*wtmp
, *wtmp2
;
152 if (mtmp
->mx
== x
&& mtmp
->my
== y
) /* hit headon */
155 /* cutting goes best with axe or sword */
157 if (weptyp
== LONG_SWORD
|| weptyp
== TWO_HANDED_SWORD
||
163 /* if tail then worm just loses a tail segment */
166 if (wtmp
->wx
== x
&& wtmp
->wy
== y
) {
167 wsegs
[tmp
] = wtmp
->nseg
;
172 /* cut the worm in two halves */
175 mtmp2
->mxlth
= mtmp2
->mnamelth
= 0;
177 /* sometimes the tail end dies */
178 if (rn2(3) || !getwn(mtmp2
)) {
182 tmp2
= mtmp2
->wormno
;
183 wsegs
[tmp2
] = wsegs
[tmp
];
187 if (wtmp
->nseg
->wx
== x
&& wtmp
->nseg
->wy
== y
) {
190 wsegs
[tmp
] = wtmp
->nseg
->nseg
;
194 pline("You cut the worm in half.");
195 mtmp2
->mhpmax
= mtmp2
->mhp
=
196 d(mtmp2
->data
->mlevel
, 8);
197 mtmp2
->mx
= wtmp
->wx
;
198 mtmp2
->my
= wtmp
->wy
;
203 pline("You cut off part of the worm's tail.");
213 } while (wtmp
->nseg
);
214 panic("Cannot find worm segment");
218 remseg(struct wseg
*wtmp
)
221 newsym(wtmp
->wx
, wtmp
->wy
);