worm.c (4225B)
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* worm.c - version 1.0.2 */ 3 4 #include "hack.h" 5 #ifndef NOWORM 6 #include "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 /**/