||This article or section is incomplete. It doesn't have all of the necessary core information on this topic. Please help the SRB2 Wiki by finishing this article.
||This article or section is outdated and has not been updated to reflect the release of SRB2 v2.2.
Please help the Wiki by correcting or removing any misinformation, as well as adding any new information to the page.
Rewrite description for 2.2.0, in particular Egg Guard has new behavior up until the second phase
A_GuardChase is an action which is a modified
A_Chase for the Egg Guard. When the actor's tracer (in the Egg Guard's case, this is its shield) has been destroyed, the actor will go to its
MF_SHOOTABLE are added to the actor's flags to allow the actor to be destroyed as with regular enemies. If the actor's target doesn't exist or is dead, the actor will look for a new target player; if none can be found, it returns to its
Speed sets the distance in fracunits the actor will move to chase the target player each time the action is used. If the actor has
MF2_AMBUSH, it will move twice the distance each time. Each time this action is used, the actor's reaction time will be reduced by 1 until it reaches 0. If the actor's tracer is still present, the actor will also force its tracer to use its current state's action whenever this action is used.
|Goes back to this state if no players can be found
|Goes to this state when the shield has been destroyed
|Distance to move, measured in fracunits (if the actor has |
MF2_AMBUSH, this value is doubled)
Code – A_GuardChase
// Function: A_GuardChase
// Description: Modified A_Chase for Egg Guard
// var1 = unused
// var2 = unused
void A_GuardChase(mobj_t *actor)
if (LUA_CallAction("A_GuardChase", actor))
if (actor->threshold != 42) // In formation...
if (!actor->tracer || !actor->tracer->health)
actor->threshold = 42;
actor->flags |= MF_SPECIAL|MF_SHOOTABLE;
speed = actor->extravalue1*actor->scale;
if (actor->flags2 & MF2_AMBUSH)
speed <<= 1;
actor->x + P_ReturnThrustX(actor, actor->angle, speed),
actor->y + P_ReturnThrustY(actor, actor->angle, speed),
&& speed > 0) // can't be the same check as previous so that P_TryMove gets to happen.
if (actor->spawnpoint && ((actor->spawnpoint->options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_OBJECTSPECIAL))
actor->angle += ANGLE_90;
else if (actor->spawnpoint && ((actor->spawnpoint->options & (MTF_EXTRA|MTF_OBJECTSPECIAL)) == MTF_EXTRA))
actor->angle -= ANGLE_90;
actor->angle += ANGLE_180;
if (actor->extravalue1 < actor->info->speed)
else // Break ranks!
// 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;
if (!actor->target || !(actor->target->flags & MF_SHOOTABLE))
// look for a new target
if (P_LookForPlayers(actor, true, false, 0))
return; // got a new target
// possibly choose another target
if (multiplayer && (actor->target->health <= 0 || !P_CheckSight(actor, actor->target))
&& P_LookForPlayers(actor, true, false, 0))
return; // got a new target
// chase towards player
if (--actor->movecount < 0 || !P_Move(actor, (actor->flags2 & MF2_AMBUSH) ? actor->info->speed * 2 : actor->info->speed))
actor->movecount += 5; // Increase tics before change in direction allowed.
// Now that we've moved, its time for our shield to move!
// Otherwise it'll never act as a proper overlay.
if (actor->tracer && actor->tracer->state
var1 = actor->tracer->state->var1, var2 = actor->tracer->state->var2;