A_EggShield is an action that is used as the thinker for the Egg Guard's shield. For each use of the action, the actor will re-position itself so that it will be placed a fracunit in front of its target, and the actor's gravity and scale settings will be adjusted accordingly with the settings for the actor's target. This action should be called every tic for the actor to continuously follow its target in this manner. If the actor's target does not exist or has no health, the actor will remove itself from existence.
The actor will also push all players touching it at the front away from it, thrusting them at the change in XY-position the actor moved during the use of this action. This feature does not affect players who are currently spectators.
Code – A_EggShield
|
|
// Function: A_EggShield
//
// Description: Modified A_Chase for Egg Guard's shield
//
// var1 = unused
// var2 = unused
//
void A_EggShield(mobj_t *actor)
{
INT32 i;
player_t *player;
fixed_t blockdist;
fixed_t newx, newy;
fixed_t movex, movey;
angle_t angle;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_EggShield", actor))
return;
#endif
if (!actor->target || !actor->target->health)
{
P_RemoveMobj(actor);
return;
}
newx = actor->target->x + P_ReturnThrustX(actor, actor->target->angle, FixedMul(FRACUNIT, actor->scale));
newy = actor->target->y + P_ReturnThrustY(actor, actor->target->angle, FixedMul(FRACUNIT, actor->scale));
movex = newx - actor->x;
movey = newy - actor->y;
actor->angle = actor->target->angle;
if (actor->target->eflags & MFE_VERTICALFLIP)
{
actor->eflags |= MFE_VERTICALFLIP;
actor->z = actor->target->z + actor->target->height - actor->height;
}
else
actor->z = actor->target->z;
actor->destscale = actor->target->destscale;
P_SetScale(actor, actor->target->scale);
actor->floorz = actor->target->floorz;
actor->ceilingz = actor->target->ceilingz;
if (!movex && !movey)
return;
P_UnsetThingPosition(actor);
actor->x = newx;
actor->y = newy;
P_SetThingPosition(actor);
// Search for players to push
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
player = &players[i];
if (!player->mo)
continue;
if (player->mo->z > actor->z + actor->height)
continue;
if (player->mo->z + player->mo->height < actor->z)
continue;
blockdist = actor->radius + player->mo->radius;
if (abs(actor->x - player->mo->x) >= blockdist || abs(actor->y - player->mo->y) >= blockdist)
continue; // didn't hit it
angle = R_PointToAngle2(actor->x, actor->y, player->mo->x, player->mo->y) - actor->angle;
if (angle > ANGLE_90 && angle < ANGLE_270)
continue;
// Blocked by the shield
player->mo->momx += movex;
player->mo->momy += movey;
return;
}
}
|
|