|
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.
|
A_SkimChase is an action which is used as the thinker for the Skim. The actor moves after the player just like with A_Chase
, moving a distance of Speed
fracunits each time the action is used. If the actor's target doesn't exist or is dead, the actor will look for a new target player; unlike A_Chase
, however, it will not return to its SpawnState
if none can be found.
The actor will occasionally use its MeleeState
or MissileState
to attack the player, providing the actor actually has a MeleeState
or MissileState
set. When the actor's MeleeState
is used, AttackSound
is played. Unlike A_Chase
, however, whether the actor will use these or not is not adjustable.
Each time this action is used, the actor's reaction time will be reduced by 1 until it reaches 0.
Object property |
Use
|
MeleeState |
Attack state 1
|
MissileState |
Attack state 2
|
AttackSound |
Sound for attack state 1
|
Speed |
Distance to move, measured in fracunits
|
Code – A_SkimChase
|
|
// Function: A_SkimChase
//
// Description: Thinker/Chase routine for Skims
//
// var1 = unused
// var2 = unused
//
void A_SkimChase(mobj_t *actor)
{
INT32 delta;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_SkimChase", actor))
return;
#endif
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
P_LookForPlayers(actor, true, false, 0);
// the spawnstate for skims already calls this function so just return either way
// without changing state
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 (actor->info->meleestate && P_SkimCheckMeleeRange(actor))
{
if (actor->info->attacksound)
S_StartAttackSound(actor, actor->info->attacksound);
P_SetMobjState(actor, actor->info->meleestate);
return;
}
// check for missile attack
if (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);
}
|
|