|
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.
|
|
To do More info needed on conditions for MeleeState and MissileState attacks
|
A_Chase is an action that makes the actor move towards the player in the most direct of the eight cardinal directions (north, northeast, east, etc). The distance to move, in fracunits, is set by the actor's Speed
property. This action strictly alters the actor's position; momentum is not modified. When used repeatedly, it works well for the basic movement of grunt enemies such as the Crawlas. If the actor's target does not exist or is dead, the actor will look for a new target player; if none can be found, it returns to its SpawnState
.
If Var1 is set to 0, the actor will use its MeleeState
or MissileState
to attack the player when certain conditions are met, provided the actor actually has the respective states set. Note that the MeleeState
attack's conditions will be checked first. When the actor's MeleeState
is used, the actor's AttackSound
is played; this is not the case for the MissileState
. If Var1 is set to 1, the MeleeState
is not used. If set to 2, the MissileState
is not used. If set to 3, neither are used.
If the actor uses its MissileState
, MF2_JUSTATTACKED
will be applied to the actor's secondary flags to prevent the actor from attacking again for the single next use of this action, after which MF2_JUSTATTACKED
will be removed and the actor can continue as usual.
Each time this action is used, the actor's reaction time will be reduced by 1 until it reaches 0.
Object property |
Use
|
SpawnState |
Goes back to this state if no players can be found
|
MeleeState |
Attack state 1 (Unless Var1 = 1 or 3)
|
MissileState |
Attack state 2 (Unless Var1 = 2 or 3)
|
AttackSound |
Sound for attack state 1 (Unless Var1 = 1 or 3)
|
Speed |
Distance to move, measured in fracunits
|
Var1 |
Effect
|
0 |
Both MeleeState and MissileState are used
|
1 |
MissileState is used; MeleeState is not used
|
2 |
MeleeState is used; MissileState is not used
|
3 |
Both MeleeState and MissileState are not used
|
Code – A_Chase
|
|
// Function: A_Chase
//
// Description: Chase after your target.
//
// var1:
// 1 = don't check meleestate
// 2 = don't check missilestate
// 3 = don't check meleestate and missilestate
// var2 = unused
//
void A_Chase(mobj_t *actor)
{
INT32 delta;
INT32 locvar1 = var1;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_Chase", actor))
return;
#endif
I_Assert(actor != NULL);
I_Assert(!P_MobjWasRemoved(actor));
if (actor->reactiontime)
actor->reactiontime--;
// modify target threshold
if (actor->threshold)
{
if (!actor->target || actor->target->health <= 0)
actor->threshold = 0;
else
actor->threshold--;
}
// 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
P_SetMobjStateNF(actor, actor->info->spawnstate);
return;
}
// do not attack twice in a row
if (actor->flags2 & MF2_JUSTATTACKED)
{
actor->flags2 &= ~MF2_JUSTATTACKED;
P_NewChaseDir(actor);
return;
}
// check for melee attack
if (!(locvar1 & 1) && actor->info->meleestate && P_CheckMeleeRange(actor))
{
if (actor->info->attacksound)
S_StartAttackSound(actor, actor->info->attacksound);
P_SetMobjState(actor, actor->info->meleestate);
return;
}
// check for missile attack
if (!(locvar1 & 2) && actor->info->missilestate)
{
if (actor->movecount || !P_CheckMissileRange(actor))
goto nomissile;
P_SetMobjState(actor, actor->info->missilestate);
actor->flags2 |= MF2_JUSTATTACKED;
return;
}
nomissile:
// possibly choose another target
if (multiplayer && !actor->threshold && (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->info->speed))
P_NewChaseDir(actor);
}
|
|
Variants of A_Chase
Actions that use A_Chase internally