// Function: A_Boss1Laser
//
// Description: Shoot an object at your target ala Bosses:
//
// var1 = object # to shoot
// var2:
// 0 - Boss 1 Left side
// 1 - Boss 1 Right side
// 2 - Triple laser
// 3 - Boss 1 Middle
// >=3 - Generic middle
//
void A_Boss1Laser(mobj_t *actor)
{
fixed_t x, y, z, floorz, speed;
INT32 locvar1 = var1;
INT32 locvar2 = (var2 & 65535);
INT32 upperend = (var2>>16);
INT32 i;
angle_t angle;
mobj_t *point;
tic_t dur;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Boss1Laser", actor))
return;
#endif
if (!actor->target)
return;
if (actor->state->tics > 1)
dur = actor->tics;
else
{
if ((upperend & 1) && (actor->extravalue2 > 1))
actor->extravalue2--;
dur = actor->extravalue2;
}
switch (locvar2)
{
case 0:
x = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
if (actor->eflags & MFE_VERTICALFLIP)
z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height;
else
z = actor->z + FixedMul(56*FRACUNIT, actor->scale);
break;
case 1:
x = actor->x + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale));
if (actor->eflags & MFE_VERTICALFLIP)
z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height;
else
z = actor->z + FixedMul(56*FRACUNIT, actor->scale);
break;
case 2:
var2 = 3; // Fire middle laser
A_Boss1Laser(actor);
var2 = 0; // Fire left laser
A_Boss1Laser(actor);
var2 = 1; // Fire right laser
A_Boss1Laser(actor);
return;
break;
case 3:
x = actor->x + P_ReturnThrustX(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale));
y = actor->y + P_ReturnThrustY(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale));
z = actor->z + actor->height/2;
break;
default:
x = actor->x;
y = actor->y;
z = actor->z + actor->height/2;
break;
}
if (!(actor->flags2 & MF2_FIRING) && dur > 1)
{
actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);
if (mobjinfo[locvar1].seesound)
S_StartSound(actor, mobjinfo[locvar1].seesound);
point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET);
point->angle = actor->angle;
point->fuse = dur+1;
P_SetTarget(&point->target, actor->target);
P_SetTarget(&actor->target, point);
}
angle = R_PointToAngle2(z + (mobjinfo[locvar1].height>>1), 0, actor->target->z, R_PointToDist2(x, y, actor->target->x, actor->target->y));
point = P_SpawnMobj(x, y, z, locvar1);
P_SetTarget(&point->target, actor);
point->angle = actor->angle;
speed = point->radius*2;
point->momz = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), speed);
point->momx = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINECOSINE(point->angle>>ANGLETOFINESHIFT), speed));
point->momy = FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), FixedMul(FINESINE(point->angle>>ANGLETOFINESHIFT), speed));
for (i = 0; i < 256; i++)
{
mobj_t *mo = P_SpawnMobj(point->x, point->y, point->z, point->type);
mo->angle = point->angle;
P_UnsetThingPosition(mo);
mo->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY;
P_SetThingPosition(mo);
x = point->x, y = point->y, z = point->z;
if (P_RailThinker(point))
break;
}
floorz = P_FloorzAtPos(x, y, z, mobjinfo[MT_EGGMOBILE_FIRE].height);
if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1)
{
point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE);
P_SetTarget(&point->target, actor);
point->destscale = 3*FRACUNIT;
point->scalespeed = FRACUNIT>>2;
point->fuse = TICRATE;
}
if (dur > 1)
actor->flags2 |= MF2_FIRING;
else
actor->flags2 &= ~MF2_FIRING;
}