| 3540 | } |
| 3541 | |
| 3542 | void MAI_Ranged(int i, int missile_type, BOOL special) |
| 3543 | { |
| 3544 | int md; |
| 3545 | int fx, fy, mx, my; |
| 3546 | MonsterStruct *Monst; |
| 3547 | |
| 3548 | if ((DWORD)i >= MAXMONSTERS) |
| 3549 | app_fatal("MAI_Ranged: Invalid monster %d", i); |
| 3550 | |
| 3551 | if (monster[i]._mmode != MM_STAND) { |
| 3552 | return; |
| 3553 | } |
| 3554 | |
| 3555 | Monst = monster + i; |
| 3556 | if (Monst->_msquelch == UCHAR_MAX || Monst->_mFlags & MFLAG_TARGETS_MONSTER) { |
| 3557 | fx = Monst->_menemyx; |
| 3558 | fy = Monst->_menemyy; |
| 3559 | mx = Monst->_mx - fx; |
| 3560 | my = Monst->_my - fy; |
| 3561 | md = M_GetDir(i); |
| 3562 | if (Monst->_msquelch < UCHAR_MAX) |
| 3563 | MonstCheckDoors(i); |
| 3564 | Monst->_mdir = md; |
| 3565 | if (Monst->_mVar1 == MM_RATTACK) { |
| 3566 | M_StartDelay(i, random_(118, 20)); |
| 3567 | } else if (abs(mx) < 4 && abs(my) < 4) { |
| 3568 | if (random_(119, 100) < 10 * (Monst->_mint + 7)) |
| 3569 | M_CallWalk(i, opposite[md]); |
| 3570 | } |
| 3571 | if (Monst->_mmode == MM_STAND) { |
| 3572 | if (LineClear(Monst->_mx, Monst->_my, fx, fy)) { |
| 3573 | if (special) |
| 3574 | M_StartRSpAttack(i, missile_type, 4); |
| 3575 | else |
| 3576 | M_StartRAttack(i, missile_type, 4); |
| 3577 | } else { |
| 3578 | Monst->_mAnimData = Monst->MType->Anims[MA_STAND].Data[md]; |
| 3579 | } |
| 3580 | } |
| 3581 | } else if (Monst->_msquelch != 0) { |
| 3582 | fx = Monst->_lastx; |
| 3583 | fy = Monst->_lasty; |
| 3584 | md = GetDirection(Monst->_mx, Monst->_my, fx, fy); |
| 3585 | M_CallWalk(i, md); |
| 3586 | } |
| 3587 | } |
| 3588 | |
| 3589 | void MAI_GoatBow(int i) |
| 3590 | { |
no test coverage detected