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