// Function: A_DetonChase
//
// Description: Chases a Deton after a player.
//
// var1 = unused
// var2 = unused
//
void A_DetonChase(mobj_t *actor)
{
angle_t exact;
fixed_t xydist, dist;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_DetonChase", actor))
return;
#endif
// modify tracer threshold
if (!actor->tracer || actor->tracer->health <= 0)
actor->threshold = 0;
else
actor->threshold = 1;
if (!actor->tracer || !(actor->tracer->flags & MF_SHOOTABLE))
{
// look for a new target
if (P_LookForPlayers(actor, true, true, 0))
return; // got a new target
actor->momx = actor->momy = actor->momz = 0;
P_SetMobjState(actor, actor->info->spawnstate);
return;
}
if (multiplayer && !actor->threshold && P_LookForPlayers(actor, true, true, 0))
return; // got a new target
// Face movement direction if not doing so
exact = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
actor->angle = exact;
/*if (exact != actor->angle)
{
if (exact - actor->angle > ANGLE_180)
{
actor->angle -= actor->info->raisestate;
if (exact - actor->angle < ANGLE_180)
actor->angle = exact;
}
else
{
actor->angle += actor->info->raisestate;
if (exact - actor->angle > ANGLE_180)
actor->angle = exact;
}
}*/
// movedir is up/down angle: how much it has to go up as it goes over to the player
xydist = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y);
exact = R_PointToAngle2(0, 0, xydist, actor->tracer->z - actor->z);
actor->movedir = exact;
/*if (exact != actor->movedir)
{
if (exact - actor->movedir > ANGLE_180)
{
actor->movedir -= actor->info->raisestate;
if (exact - actor->movedir < ANGLE_180)
actor->movedir = exact;
}
else
{
actor->movedir += actor->info->raisestate;
if (exact - actor->movedir > ANGLE_180)
actor->movedir = exact;
}
}*/
// check for melee attack
if (actor->tracer)
{
if (P_AproxDistance(actor->tracer->x-actor->x, actor->tracer->y-actor->y) < actor->radius+actor->tracer->radius)
{
if (!((actor->tracer->z > actor->z + actor->height) || (actor->z > actor->tracer->z + actor->tracer->height)))
{
P_ExplodeMissile(actor);
return;
}
}
}
// chase towards player
if ((dist = P_AproxDistance(xydist, actor->tracer->z-actor->z))
> FixedMul((actor->info->painchance << FRACBITS), actor->scale))
{
P_SetTarget(&actor->tracer, NULL); // Too far away
return;
}
if (actor->reactiontime == 0)
{
actor->reactiontime = actor->info->reactiontime;
return;
}
if (actor->reactiontime > 1)
{
actor->reactiontime--;
return;
}
if (actor->reactiontime > 0)
{
actor->reactiontime = -42;
if (actor->info->seesound)
S_StartScreamSound(actor, actor->info->seesound);
}
if (actor->reactiontime == -42)
{
fixed_t xyspeed;
actor->reactiontime = -42;
exact = actor->movedir>>ANGLETOFINESHIFT;
xyspeed = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINECOSINE(exact));
actor->momz = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINESINE(exact));
exact = actor->angle>>ANGLETOFINESHIFT;
actor->momx = FixedMul(xyspeed, FINECOSINE(exact));
actor->momy = FixedMul(xyspeed, FINESINE(exact));
// Variable re-use
xyspeed = (P_AproxDistance(actor->tracer->x - actor->x, P_AproxDistance(actor->tracer->y - actor->y, actor->tracer->z - actor->z))>>(FRACBITS+6));
if (xyspeed < 1)
xyspeed = 1;
if (leveltime % xyspeed == 0)
S_StartSound(actor, sfx_deton);
}
}