// Function: A_Boss7Chase
//
// Description: Like A_Chase, but for Black Eggman
//
// var1 = unused
// var2 = unused
//
void A_Boss7Chase(mobj_t *actor)
{
INT32 delta;
INT32 i;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Boss7Chase", actor))
return;
#endif
if (actor->z != actor->floorz)
return;
// Self-adjust if stuck on the edge
if (actor->tracer)
{
if (P_AproxDistance(actor->x - actor->tracer->x, actor->y - actor->tracer->y) > 128*FRACUNIT - actor->radius)
P_InstaThrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), FRACUNIT);
}
if (actor->flags2 & MF2_FRET)
{
P_SetMobjState(actor, S_BLACKEGG_DESTROYPLAT1);
S_StartSound(0, sfx_s3k53);
actor->flags2 &= ~MF2_FRET;
return;
}
// turn towards movement direction if not there yet
if (actor->movedir < NUMDIRS)
{
actor->angle &= (7<<29);
delta = actor->angle - (actor->movedir << 29);
if (delta > 0)
actor->angle -= ANGLE_45;
else if (delta < 0)
actor->angle += ANGLE_45;
}
// Is a player on top of us?
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
if (players[i].mo->health <= 0)
continue;
if (P_AproxDistance(players[i].mo->x - actor->x, players[i].mo->y - actor->y) > actor->radius)
continue;
if (players[i].mo->z > actor->z + actor->height - 2*FRACUNIT
&& players[i].mo->z < actor->z + actor->height + 32*FRACUNIT)
{
// Punch him!
P_SetMobjState(actor, actor->info->meleestate);
S_StartSound(0, sfx_begrnd); // warning sound
return;
}
}
if (actor->health <= actor->info->damage
&& actor->target
&& actor->target->player
&& (actor->target->player->powers[pw_carry] == CR_GENERIC))
{
A_FaceTarget(actor);
P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
actor->movecount = TICRATE + P_RandomByte()/2;
return;
}
if (actor->reactiontime)
actor->reactiontime--;
if (actor->reactiontime <= 0 && actor->z == actor->floorz)
{
// Here, we'll call P_RandomByte() and decide what kind of attack to do
switch(actor->threshold)
{
case 0: // Lob cannon balls
if (actor->z < 1056*FRACUNIT)
{
A_FaceTarget(actor);
P_SetMobjState(actor, actor->info->xdeathstate);
actor->movecount = 7*TICRATE + P_RandomByte();
break;
}
actor->threshold++;
/* FALLTHRU */
case 1: // Chaingun Goop
A_FaceTarget(actor);
P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
if (actor->health > actor->info->damage)
actor->movecount = TICRATE + P_RandomByte()/3;
else
actor->movecount = TICRATE + P_RandomByte()/2;
break;
case 2: // Homing Missile
A_FaceTarget(actor);
P_SetMobjState(actor, actor->info->missilestate);
S_StartSound(0, sfx_beflap);
break;
}
actor->threshold++;
actor->threshold %= 3;
return;
}
// possibly choose another target
if (multiplayer && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target))
&& P_BossTargetPlayer(actor, false))
return; // got a new target
if (leveltime & 1)
{
// chase towards player
if (--actor->movecount < 0 || !P_Move(actor, actor->info->speed))
P_NewChaseDir(actor);
}
}