|
|
|
|
//========= Copyright <EFBFBD> 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
|
|
|
//
|
|
|
|
|
// Purpose: NPC does a pounce attack against his enemy when close enough. Uses MeleeAttack2Conditions.
|
|
|
|
|
//
|
|
|
|
|
//=============================================================================//
|
|
|
|
|
|
|
|
|
|
#include "cbase.h"
|
|
|
|
|
#include "beam_shared.h"
|
|
|
|
|
#include "ai_motor.h"
|
|
|
|
|
#include "asw_ai_behavior_pounce.h"
|
|
|
|
|
#include "ai_hint.h"
|
|
|
|
|
#include "ai_navigator.h"
|
|
|
|
|
#include "ai_memory.h"
|
|
|
|
|
#include "asw_alien.h"
|
|
|
|
|
#include "asw_marine.h"
|
|
|
|
|
#include "asw_gamerules.h"
|
|
|
|
|
|
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
|
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN_DATADESC( CAI_ASW_PounceBehavior )
|
|
|
|
|
END_DATADESC();
|
|
|
|
|
|
|
|
|
|
LINK_BEHAVIOR_TO_CLASSNAME( CAI_ASW_PounceBehavior );
|
|
|
|
|
|
|
|
|
|
Activity ACT_ALIEN_POUNCE;
|
|
|
|
|
Activity ACT_ALIEN_POUNCE_HIT;
|
|
|
|
|
Activity ACT_ALIEN_POUNCE_MISS;
|
|
|
|
|
|
|
|
|
|
#define POUNCE_THINK_CONTEXT "PounceThinkContext"
|
|
|
|
|
|
|
|
|
|
extern ConVar sv_gravity;
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: constructor
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
CAI_ASW_PounceBehavior::CAI_ASW_PounceBehavior( )
|
|
|
|
|
{
|
|
|
|
|
m_flMinRange = 0.0f;
|
|
|
|
|
m_flMaxRange = 100.0f;
|
|
|
|
|
m_flAttackDotAngle = 0.7f;
|
|
|
|
|
m_flPounceInterval = 0.0f;
|
|
|
|
|
m_flNextPounceTime = 0.0f;
|
|
|
|
|
m_flPounceDistance = 300.0f;
|
|
|
|
|
m_flPounceDamage = 15.0f;
|
|
|
|
|
m_flIgnoreWorldCollisionTime = 0.0f;
|
|
|
|
|
m_bMidPounce = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: function to set up parameters
|
|
|
|
|
// Input : szKeyName - the name of the key
|
|
|
|
|
// szValue - the value to be set
|
|
|
|
|
// Output : returns true of we handled this key
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
bool CAI_ASW_PounceBehavior::KeyValue( const char *szKeyName, const char *szValue )
|
|
|
|
|
{
|
|
|
|
|
if ( V_stricmp( szKeyName, "min_range" ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
m_flMinRange = atof( szValue );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if ( V_stricmp( szKeyName, "max_range" ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
m_flMaxRange = atof( szValue );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if ( V_stricmp( szKeyName, "attack_dot_angle" ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
m_flAttackDotAngle = atof( szValue );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if ( V_stricmp( szKeyName, "pounce_interval" ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
m_flPounceInterval = atof( szValue );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if ( V_stricmp( szKeyName, "pounce_distance" ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
m_flPounceDistance = atof( szValue );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if ( V_stricmp( szKeyName, "pounce_damage" ) == 0 )
|
|
|
|
|
{
|
|
|
|
|
m_flPounceDamage = atof( szValue );
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return BaseClass::KeyValue( szKeyName, szValue );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: precaches any additional assets this behavior needs
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
void CAI_ASW_PounceBehavior::Precache( void )
|
|
|
|
|
{
|
|
|
|
|
BaseClass::Precache();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose:
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
void CAI_ASW_PounceBehavior::Init( )
|
|
|
|
|
{
|
|
|
|
|
CASW_Alien *pNPC = static_cast< CASW_Alien * >( GetOuter() );
|
|
|
|
|
if ( !pNPC )
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pNPC->meleeAttack2.Init( m_flMinRange, m_flMaxRange, m_flAttackDotAngle, true );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: determines if we can use this behavior currently
|
|
|
|
|
// Output : returns true if this behavior is able to run
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
bool CAI_ASW_PounceBehavior::CanSelectSchedule()
|
|
|
|
|
{
|
|
|
|
|
if ( !GetOuter()->IsInterruptable() )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( gpGlobals->curtime < m_flNextPounceTime )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !HasCondition( COND_CAN_MELEE_ATTACK2 ) && !HasCondition( COND_TOO_CLOSE_TO_ATTACK ) )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return BaseClass::CanSelectSchedule();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: sets / clears conditions for when the behavior is active. this is
|
|
|
|
|
// generally a larger set of conditions to interrupt any tasks.
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
void CAI_ASW_PounceBehavior::GatherConditions( )
|
|
|
|
|
{
|
|
|
|
|
BaseClass::GatherConditions();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: sets / clears conditions for when the behavior is not active. this is
|
|
|
|
|
// mainly to have a smaller set of conditions to wake up the behavior.
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
void CAI_ASW_PounceBehavior::GatherConditionsNotActive( )
|
|
|
|
|
{
|
|
|
|
|
BaseClass::GatherConditionsNotActive();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: general purpose routine to collect conditions used both during active
|
|
|
|
|
// and non-active states of the behavior.
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
void CAI_ASW_PounceBehavior::GatherCommonConditions( )
|
|
|
|
|
{
|
|
|
|
|
BaseClass::GatherCommonConditions();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CAI_ASW_PounceBehavior::BeginScheduleSelection( )
|
|
|
|
|
{
|
|
|
|
|
SetBehaviorParam( m_StatusParm, -1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose: routine called to select what schedule we want to run
|
|
|
|
|
// Output : returns the schedule id of the schedule we want to run
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
int CAI_ASW_PounceBehavior::SelectSchedule()
|
|
|
|
|
{
|
|
|
|
|
if ( HasCondition(COND_TOO_CLOSE_TO_ATTACK) )
|
|
|
|
|
return SCHED_BACK_AWAY_FROM_ENEMY;
|
|
|
|
|
|
|
|
|
|
m_flNextPounceTime = gpGlobals->curtime + m_flPounceInterval;
|
|
|
|
|
|
|
|
|
|
return SCHED_ALIEN_POUNCE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
// Purpose:
|
|
|
|
|
// Input :
|
|
|
|
|
// Output :
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
void CAI_ASW_PounceBehavior::HandleBehaviorEvent( CBaseEntity *pInflictor, BehaviorEvent_t eEvent, int nParm )
|
|
|
|
|
{
|
|
|
|
|
switch( eEvent )
|
|
|
|
|
{
|
|
|
|
|
case BEHAVIOR_EVENT_POUNCE:
|
|
|
|
|
{
|
|
|
|
|
CASW_Alien *pOwner = static_cast< CASW_Alien * >( GetOuter() );
|
|
|
|
|
|
|
|
|
|
if ( pOwner->GetEnemy() )
|
|
|
|
|
{
|
|
|
|
|
// jump straight ahead
|
|
|
|
|
Vector vecForward;
|
|
|
|
|
AngleVectors( pOwner->EyeAngles(), &vecForward );
|
|
|
|
|
vecForward.z = 0;
|
|
|
|
|
vecForward.NormalizeInPlace();
|
|
|
|
|
PounceAttack( false, GetAbsOrigin() + vecForward * m_flPounceDistance );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define ALIEN_IGNORE_WORLD_COLLISION_TIME 0.5
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: Does a jump attack at the given position.
|
|
|
|
|
// Input : bRandomJump - Just hop in a random direction.
|
|
|
|
|
// vecPos - Position to jump at, ignored if bRandom is set to true.
|
|
|
|
|
// bThrown -
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
void CAI_ASW_PounceBehavior::PounceAttack( bool bRandomJump, const Vector &vecPos, bool bThrown, float flBaseHeight, float flAdditionalHeight )
|
|
|
|
|
{
|
|
|
|
|
Vector vecJumpVel;
|
|
|
|
|
if ( !bRandomJump )
|
|
|
|
|
{
|
|
|
|
|
float gravity = sv_gravity.GetFloat();
|
|
|
|
|
if ( gravity <= 1 )
|
|
|
|
|
{
|
|
|
|
|
gravity = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// How fast does the headcrab need to travel to reach the position given gravity?
|
|
|
|
|
float flActualHeight = vecPos.z - GetAbsOrigin().z;
|
|
|
|
|
float height = flActualHeight;
|
|
|
|
|
if ( height < 16 )
|
|
|
|
|
{
|
|
|
|
|
height = flBaseHeight; //60; //16;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
float flMaxHeight = bThrown ? 400 : 120;
|
|
|
|
|
if ( height > flMaxHeight )
|
|
|
|
|
{
|
|
|
|
|
height = flMaxHeight;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// overshoot the jump by an additional 8 inches
|
|
|
|
|
// NOTE: This calculation jumps at a position INSIDE the box of the enemy (player)
|
|
|
|
|
// so if you make the additional height too high, the crab can land on top of the
|
|
|
|
|
// enemy's head. If we want to jump high, we'll need to move vecPos to the surface/outside
|
|
|
|
|
// of the enemy's box.
|
|
|
|
|
|
|
|
|
|
float additionalHeight = 0;
|
|
|
|
|
if ( height < 32 )
|
|
|
|
|
{
|
|
|
|
|
additionalHeight = flAdditionalHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
height += additionalHeight;
|
|
|
|
|
|
|
|
|
|
// NOTE: This equation here is from vf^2 = vi^2 + 2*a*d
|
|
|
|
|
float speed = sqrt( 2 * gravity * height );
|
|
|
|
|
float time = speed / gravity;
|
|
|
|
|
|
|
|
|
|
// add in the time it takes to fall the additional height
|
|
|
|
|
// So the impact takes place on the downward slope at the original height
|
|
|
|
|
time += sqrt( (2 * additionalHeight) / gravity );
|
|
|
|
|
|
|
|
|
|
// Scale the sideways velocity to get there at the right time
|
|
|
|
|
VectorSubtract( vecPos, GetAbsOrigin(), vecJumpVel );
|
|
|
|
|
vecJumpVel /= time;
|
|
|
|
|
|
|
|
|
|
// Speed to offset gravity at the desired height.
|
|
|
|
|
vecJumpVel.z = speed;
|
|
|
|
|
|
|
|
|
|
// Don't jump too far/fast.
|
|
|
|
|
float flJumpSpeed = vecJumpVel.Length();
|
|
|
|
|
float flMaxSpeed = bThrown ? 1000.0f : 650.0f;
|
|
|
|
|
if ( flJumpSpeed > flMaxSpeed )
|
|
|
|
|
{
|
|
|
|
|
vecJumpVel *= flMaxSpeed / flJumpSpeed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//
|
|
|
|
|
// Jump hop, don't care where.
|
|
|
|
|
//
|
|
|
|
|
Vector forward, up;
|
|
|
|
|
AngleVectors( GetLocalAngles(), &forward, NULL, &up );
|
|
|
|
|
vecJumpVel = Vector( forward.x, forward.y, up.z ) * 350;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//AttackSound();
|
|
|
|
|
Leap( vecJumpVel );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CAI_ASW_PounceBehavior::Leap( const Vector &vecVel )
|
|
|
|
|
{
|
|
|
|
|
m_bMidPounce = true;
|
|
|
|
|
|
|
|
|
|
SetCondition( COND_FLOATING_OFF_GROUND );
|
|
|
|
|
SetGroundEntity( NULL );
|
|
|
|
|
|
|
|
|
|
m_flIgnoreWorldCollisionTime = gpGlobals->curtime + ALIEN_IGNORE_WORLD_COLLISION_TIME;
|
|
|
|
|
|
|
|
|
|
if( HasHeadroom() )
|
|
|
|
|
{
|
|
|
|
|
// Take him off ground so engine doesn't instantly reset FL_ONGROUND.
|
|
|
|
|
UTIL_SetOrigin( GetOuter(), GetLocalOrigin() + Vector( 0, 0, 1 ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GetOuter()->SetAbsVelocity( vecVel );
|
|
|
|
|
|
|
|
|
|
// think every frame so the player sees the alien where it is
|
|
|
|
|
|
|
|
|
|
GetOuter()->SetContextThink( &CASW_Alien::CallBehaviorThink, gpGlobals->curtime, POUNCE_THINK_CONTEXT );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CAI_ASW_PounceBehavior::HasHeadroom()
|
|
|
|
|
{
|
|
|
|
|
trace_t tr;
|
|
|
|
|
UTIL_TraceEntity( GetOuter(), GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, 1 ), MASK_NPCSOLID, GetOuter(), GetCollisionGroup(), &tr );
|
|
|
|
|
|
|
|
|
|
return (tr.fraction == 1.0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CAI_ASW_PounceBehavior::BehaviorThink( void )
|
|
|
|
|
{
|
|
|
|
|
if( GetOuter()->GetFlags() & FL_ONGROUND && gpGlobals->curtime >= m_flIgnoreWorldCollisionTime )
|
|
|
|
|
{
|
|
|
|
|
GetOuter()->SetAbsVelocity( vec3_origin );
|
|
|
|
|
|
|
|
|
|
GetOuter()->SetContextThink( NULL, TICK_NEVER_THINK, POUNCE_THINK_CONTEXT );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GetOuter()->SetContextThink( &CASW_Alien::CallBehaviorThink, gpGlobals->curtime, POUNCE_THINK_CONTEXT );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Purpose: LeapTouch - this is the headcrab's touch function when it is in the air.
|
|
|
|
|
// Input : *pOther -
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void CAI_ASW_PounceBehavior::StartTouch( CBaseEntity *pOther )
|
|
|
|
|
{
|
|
|
|
|
BaseClass::StartTouch( pOther );
|
|
|
|
|
|
|
|
|
|
if ( !m_bMidPounce )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if ( !pOther->ShouldCollide( GetCollisionGroup(), GetOuter()->PhysicsSolidMaskForEntity() ) )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if ( !g_pGameRules->ShouldCollide( GetCollisionGroup(), pOther->GetCollisionGroup() ) )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
bool bHit = false;
|
|
|
|
|
if ( GetOuter()->IRelationType( pOther ) == D_HT )
|
|
|
|
|
{
|
|
|
|
|
if ( pOther->m_takedamage != DAMAGE_NO && !pOther->IsWorld() )
|
|
|
|
|
{
|
|
|
|
|
Vector vecForceDir = GetOuter()->GetAbsVelocity();
|
|
|
|
|
vecForceDir.NormalizeInPlace();
|
|
|
|
|
// TODO: Check they're not behind me
|
|
|
|
|
CASW_Marine *pMarine = CASW_Marine::AsMarine( pOther );
|
|
|
|
|
if ( pMarine )
|
|
|
|
|
{
|
|
|
|
|
pMarine->Stumble( GetOuter(), vecForceDir, false );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float flDamage = ASWGameRules()->ModifyAlienDamageBySkillLevel( m_flPounceDamage );
|
|
|
|
|
flDamage = MAX( flDamage, 1.0f );
|
|
|
|
|
|
|
|
|
|
CTakeDamageInfo info( GetOuter(), GetOuter(), flDamage, DMG_SLASH );
|
|
|
|
|
const trace_t &touchTrace = GetOuter()->GetTouchTrace();
|
|
|
|
|
CalculateMeleeDamageForce( &info, vecForceDir, touchTrace.endpos );
|
|
|
|
|
pOther->TakeDamage( info );
|
|
|
|
|
|
|
|
|
|
bHit = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if( !(GetOuter()->GetFlags() & FL_ONGROUND) )
|
|
|
|
|
{
|
|
|
|
|
// Still in the air...
|
|
|
|
|
if( gpGlobals->curtime < m_flIgnoreWorldCollisionTime )
|
|
|
|
|
{
|
|
|
|
|
// Headcrabs try to ignore the world, static props, and friends for a
|
|
|
|
|
// fraction of a second after they jump. This is because they often brush
|
|
|
|
|
// doorframes or props as they leap, and touching those objects turns off
|
|
|
|
|
// this touch function, which can cause them to hit the player and not bite.
|
|
|
|
|
// A timer probably isn't the best way to fix this, but it's one of our
|
|
|
|
|
// safer options at this point (sjb).
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !pOther->IsSolid() )
|
|
|
|
|
{
|
|
|
|
|
// Touching a trigger or something.
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GetOuter()->SetAbsVelocity( vec3_origin );
|
|
|
|
|
|
|
|
|
|
if ( bHit )
|
|
|
|
|
{
|
|
|
|
|
if ( GetOuter()->HaveSequenceForActivity( (Activity) ACT_ALIEN_POUNCE_HIT ) )
|
|
|
|
|
{
|
|
|
|
|
GetOuter()->SetActivity( (Activity) ACT_ALIEN_POUNCE_HIT );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ( GetOuter()->HaveSequenceForActivity( (Activity) ACT_ALIEN_POUNCE_MISS ) )
|
|
|
|
|
{
|
|
|
|
|
GetOuter()->SetActivity( (Activity) ACT_ALIEN_POUNCE_MISS );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure we're solid
|
|
|
|
|
GetOuter()->RemoveSolidFlags( FSOLID_NOT_SOLID );
|
|
|
|
|
|
|
|
|
|
m_bMidPounce = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AI_BEGIN_CUSTOM_SCHEDULE_PROVIDER( CAI_ASW_PounceBehavior )
|
|
|
|
|
|
|
|
|
|
DECLARE_ACTIVITY( ACT_ALIEN_POUNCE )
|
|
|
|
|
DECLARE_ACTIVITY( ACT_ALIEN_POUNCE_HIT )
|
|
|
|
|
DECLARE_ACTIVITY( ACT_ALIEN_POUNCE_MISS )
|
|
|
|
|
|
|
|
|
|
// forward pounce attack
|
|
|
|
|
DEFINE_SCHEDULE
|
|
|
|
|
(
|
|
|
|
|
SCHED_ALIEN_POUNCE,
|
|
|
|
|
|
|
|
|
|
" Tasks"
|
|
|
|
|
" TASK_STOP_MOVING 0"
|
|
|
|
|
" TASK_FACE_ENEMY 0"
|
|
|
|
|
" TASK_ANNOUNCE_ATTACK 1"
|
|
|
|
|
" TASK_RESET_ACTIVITY 0"
|
|
|
|
|
" TASK_PLAY_SEQUENCE ACTIVITY:ACT_ALIEN_POUNCE"
|
|
|
|
|
|
|
|
|
|
" Interrupts"
|
|
|
|
|
" COND_TASK_FAILED"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
AI_END_CUSTOM_SCHEDULE_PROVIDER()
|
|
|
|
|
|
|
|
|
|
#include "tier0/memdbgoff.h"
|