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