* worm_move() * * Check for mon->wormno before calling this function! * * Move the worm. Maybe grow. */
| 193 | * Move the worm. Maybe grow. |
| 194 | */ |
| 195 | void |
| 196 | worm_move(struct monst *worm) |
| 197 | { |
| 198 | struct wseg *seg, *new_seg; /* new segment */ |
| 199 | int wnum = worm->wormno; /* worm number */ |
| 200 | |
| 201 | /* |
| 202 | * Place a segment at the old worm head. The head has already moved. |
| 203 | */ |
| 204 | seg = wheads[wnum]; |
| 205 | place_worm_seg(worm, seg->wx, seg->wy); |
| 206 | newsym(seg->wx, seg->wy); /* display the new segment */ |
| 207 | |
| 208 | /* |
| 209 | * Create a new dummy segment head and place it at the end of the list. |
| 210 | */ |
| 211 | new_seg = newseg(); |
| 212 | new_seg->wx = worm->mx; |
| 213 | new_seg->wy = worm->my; |
| 214 | new_seg->nseg = (struct wseg *) 0; |
| 215 | seg->nseg = new_seg; /* attach it to the end of the list */ |
| 216 | wheads[wnum] = new_seg; /* move the end pointer */ |
| 217 | |
| 218 | if (wgrowtime[wnum] <= svm.moves) { |
| 219 | int whplimit, whpcap, prev_mhp, wsegs = count_wsegs(worm); |
| 220 | |
| 221 | /* first set up for the next time to grow */ |
| 222 | if (!wgrowtime[wnum]) { |
| 223 | /* new worm; usually grow a tail segment on its next turn */ |
| 224 | wgrowtime[wnum] = svm.moves + rnd(5); |
| 225 | } else { |
| 226 | int mmove = mcalcmove(worm, FALSE), |
| 227 | /* prior to 5.0.0,, next-grow increment was 3..17 but since |
| 228 | it got checked every 4th turn when the speed 3 worm got |
| 229 | to move, it was effectively 0..5; also, its usage was |
| 230 | 'wgrowtime += incr', so often 'wgrowtime' would be |
| 231 | exceeded by 'moves' on consecutive turns for the worm, |
| 232 | resulting in an excessively rapid growth cycle */ |
| 233 | incr = rn1(10, 2); /* 2..12; after adjusting for long worn |
| 234 | * speed of 3, effective value is 8..48 */ |
| 235 | |
| 236 | incr = (incr * NORMAL_SPEED) / max(mmove, 1); |
| 237 | wgrowtime[wnum] = svm.moves + incr; |
| 238 | } |
| 239 | |
| 240 | /* increase HP based on number of segments; if it has shrunk, it |
| 241 | won't gain new HP until regaining previous peak segment count; |
| 242 | when wounded (whether from damage or from shrinking), the HP |
| 243 | which might have been 'new' will heal */ |
| 244 | whplimit = !worm->m_lev ? 4 : (8 * (int) worm->m_lev); |
| 245 | /* note: wsegs includes the hidden segment co-located with the head */ |
| 246 | if (wsegs > 33) |
| 247 | whplimit += 2 * (wsegs - 33), wsegs = 33; |
| 248 | if (wsegs > 22) |
| 249 | whplimit += 4 * (wsegs - 22), wsegs = 22; |
| 250 | if (wsegs > 11) |
| 251 | whplimit += 6 * (wsegs - 11), wsegs = 11; |
| 252 | whplimit += 8 * wsegs; |
no test coverage detected