// Function: A_FaceStabHurl
//
// Description: Facestabber hurl action
//
// var1 = homing strength (recommended strength between 0-8)
// var2 = effective nextstate
//
void A_FaceStabHurl(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
if (LUA_CallAction(A_FACESTABHURL, actor))
return;
if (actor->target)
{
angle_t visang = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y);
// Calculate new direction.
angle_t dirang = actor->angle;
angle_t diffang = visang - dirang;
if (locvar1) // Allow homing?
{
if (diffang > ANGLE_180)
{
angle_t workang = locvar1*(InvAngle(diffang)>>5);
diffang += InvAngle(workang);
}
else
diffang += (locvar1*(diffang>>5));
}
diffang += ANGLE_45;
// Check the sight cone.
if (diffang < ANGLE_90)
{
actor->angle = dirang;
if (++actor->extravalue2 < 4)
actor->extravalue2 = 4;
else if (actor->extravalue2 > 26)
actor->extravalue2 = 26;
if (P_TryMove(actor,
actor->x + P_ReturnThrustX(actor, dirang, actor->extravalue2<<FRACBITS),
actor->y + P_ReturnThrustY(actor, dirang, actor->extravalue2<<FRACBITS),
false))
{
// Do the spear damage.
#define NUMSTEPS 3
#define NUMGRADS 5
#define MAXVAL (NUMSTEPS*NUMGRADS)
SINT8 step = (++actor->extravalue1);
fixed_t basesize = FRACUNIT/MAXVAL;
mobj_t *hwork = actor;
INT32 dist = 113;
fixed_t xo = P_ReturnThrustX(actor, actor->angle, dist*basesize);
fixed_t yo = P_ReturnThrustY(actor, actor->angle, dist*basesize);
while (step > 0)
{
if (!hwork->hnext)
P_SetTarget(&hwork->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_FACESTABBERSPEAR));
hwork = hwork->hnext;
hwork->angle = actor->angle + ANGLE_90;
hwork->destscale = FixedSqrt(step*basesize);
P_SetScale(hwork, hwork->destscale);
hwork->fuse = 2;
P_TeleportMove(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<<FRACBITS)));
step -= NUMGRADS;
}
if (actor->extravalue1 >= MAXVAL)
actor->extravalue1 -= NUMGRADS;
if ((step % 5) == 0)
P_SharpDust(actor, MT_SPINDUST, actor->angle);
P_FaceStabFlume(actor);
return;
#undef MAXVAL
#undef NUMGRADS
#undef NUMSTEPS
}
}
}
P_SetMobjState(actor, locvar2);
actor->reactiontime = actor->info->reactiontime;
}