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
)
19 for(tmp
=1; tmp
<32; tmp
++) if(!wsegs
[tmp
]) {
23 return(0); /* level infested with worms */
26 /* called to initialize a worm unless cut in half */
28 initworm(struct monst
*mtmp
)
31 int tmp
= mtmp
->wormno
;
33 wheads
[tmp
] = wsegs
[tmp
] = wtmp
= newseg();
41 worm_move(struct monst
*mtmp
)
43 struct wseg
*wtmp
, *whd
;
44 int tmp
= mtmp
->wormno
;
49 (whd
= wheads
[tmp
])->nseg
= wtmp
;
51 if(cansee(whd
->wx
,whd
->wy
)){
53 atl(whd
->wx
, whd
->wy
, '~');
55 } else whd
->wdispl
= 0;
56 if(wgrowtime
[tmp
] <= moves
) {
57 if(!wgrowtime
[tmp
]) wgrowtime
[tmp
] = moves
+ rnd(5);
58 else wgrowtime
[tmp
] += 2+rnd(15);
64 wsegs
[tmp
] = whd
->nseg
;
69 worm_nomove(struct monst
*mtmp
)
75 if(wtmp
== wheads
[tmp
]) return;
76 if(wtmp
== 0 || wtmp
->nseg
== 0) panic("worm_nomove?");
77 wsegs
[tmp
] = wtmp
->nseg
;
79 mtmp
->mhp
-= 3; /* mhpmax not changed ! */
83 wormdead(struct monst
*mtmp
)
85 int tmp
= mtmp
->wormno
;
86 struct wseg
*wtmp
, *wtmp2
;
89 for(wtmp
= wsegs
[tmp
]; wtmp
; wtmp
= wtmp2
){
97 wormhit(struct monst
*mtmp
)
99 int tmp
= mtmp
->wormno
;
101 if(!tmp
) return; /* worm without tail */
102 for(wtmp
= wsegs
[tmp
]; wtmp
; wtmp
= wtmp
->nseg
)
107 wormsee(unsigned int tmp
)
109 struct wseg
*wtmp
= wsegs
[tmp
];
110 if(!wtmp
) panic("wormsee: wtmp==0");
111 for(; wtmp
->nseg
; wtmp
= wtmp
->nseg
)
112 if(!cansee(wtmp
->wx
,wtmp
->wy
) && wtmp
->wdispl
){
113 newsym(wtmp
->wx
, wtmp
->wy
);
119 pwseg(struct wseg
*wtmp
)
122 atl(wtmp
->wx
, wtmp
->wy
, '~');
128 cutworm(struct monst
*mtmp
, xchar x
, xchar y
, uchar weptyp
)
129 /* weptyp: uwep->otyp or 0 */
131 struct wseg
*wtmp
, *wtmp2
;
134 if(mtmp
->mx
== x
&& mtmp
->my
== y
) return; /* hit headon */
136 /* cutting goes best with axe or sword */
138 if(weptyp
== LONG_SWORD
|| weptyp
== TWO_HANDED_SWORD
||
139 weptyp
== AXE
) tmp
+= 5;
142 /* if tail then worm just loses a tail segment */
145 if(wtmp
->wx
== x
&& wtmp
->wy
== y
){
146 wsegs
[tmp
] = wtmp
->nseg
;
151 /* cut the worm in two halves */
154 mtmp2
->mxlth
= mtmp2
->mnamelth
= 0;
156 /* sometimes the tail end dies */
157 if(rn2(3) || !getwn(mtmp2
)){
161 tmp2
= mtmp2
->wormno
;
162 wsegs
[tmp2
] = wsegs
[tmp
];
166 if(wtmp
->nseg
->wx
== x
&& wtmp
->nseg
->wy
== y
){
167 if(tmp2
) wheads
[tmp2
] = wtmp
;
168 wsegs
[tmp
] = wtmp
->nseg
->nseg
;
172 pline("You cut the worm in half.");
173 mtmp2
->mhpmax
= mtmp2
->mhp
=
174 d(mtmp2
->data
->mlevel
, 8);
175 mtmp2
->mx
= wtmp
->wx
;
176 mtmp2
->my
= wtmp
->wy
;
181 pline("You cut off part of the worm's tail.");
188 if(!tmp2
) remseg(wtmp
);
191 panic("Cannot find worm segment");
195 remseg(struct wseg
*wtmp
)
198 newsym(wtmp
->wx
, wtmp
->wy
);