// Function: A_FocusTarget
//
// Description: Home in on your target.
//
// var1:
// 0 - accelerative focus with friction
// 1 - steady focus with fixed movement speed
// anything else - don't move
// var2:
// 0 - don't trace target, just move forwards
// & 1 - change horizontal angle
// & 2 - change vertical angle
//
void A_FocusTarget(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_FocusTarget", actor))
return;
#endif
if (actor->target)
{
fixed_t speed = FixedMul(actor->info->speed, actor->scale);
fixed_t dist = (locvar2 ? R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) : speed+1);
angle_t hangle = ((locvar2 & 1) ? R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) : actor->angle);
angle_t vangle = ((locvar2 & 2) ? R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist) : ANGLE_90);
switch(locvar1)
{
case 0:
{
actor->momx -= actor->momx>>4, actor->momy -= actor->momy>>4, actor->momz -= actor->momz>>4;
actor->momz += FixedMul(FINECOSINE(vangle>>ANGLETOFINESHIFT), speed);
actor->momx += FixedMul(FINESINE(vangle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(hangle>>ANGLETOFINESHIFT), speed));
actor->momy += FixedMul(FINESINE(vangle>>ANGLETOFINESHIFT), FixedMul(FINESINE(hangle>>ANGLETOFINESHIFT), speed));
}
break;
case 1:
if (dist > speed)
{
actor->momz = FixedMul(FINECOSINE(vangle>>ANGLETOFINESHIFT), speed);
actor->momx = FixedMul(FINESINE(vangle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(hangle>>ANGLETOFINESHIFT), speed));
actor->momy = FixedMul(FINESINE(vangle>>ANGLETOFINESHIFT), FixedMul(FINESINE(hangle>>ANGLETOFINESHIFT), speed));
}
else
{
actor->momx = 0, actor->momy = 0, actor->momz = 0;
actor->z = actor->target->z + (actor->target->height>>1);
P_TryMove(actor, actor->target->x, actor->target->y, true);
}
break;
default:
break;
}
}
}