mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2025-04-30 00:49:34 +03:00
Optional npc_helicopter damage and stealth changes
This commit is contained in:
parent
fbb7769acd
commit
3f64380755
@ -42,6 +42,10 @@ virtual void NullThink( void );
|
|||||||
|
|
||||||
ConVar g_debug_basehelicopter( "g_debug_basehelicopter", "0", FCVAR_CHEAT );
|
ConVar g_debug_basehelicopter( "g_debug_basehelicopter", "0", FCVAR_CHEAT );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
ConVar g_helicopter_use_sight_condition( "g_helicopter_use_sight_condition", "0", 0, "If enabled, helicopters will use the AI sight condition instead of just checking if there's a clear path to the player. This prevents them from cheating." );
|
||||||
|
#endif
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
// TODOs
|
// TODOs
|
||||||
@ -702,7 +706,11 @@ void CBaseHelicopter::UpdateEnemy()
|
|||||||
{
|
{
|
||||||
CBaseEntity *pEnemy = GetEnemy();
|
CBaseEntity *pEnemy = GetEnemy();
|
||||||
GatherEnemyConditions( pEnemy );
|
GatherEnemyConditions( pEnemy );
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( (g_helicopter_use_sight_condition.GetBool() && pEnemy->Classify() != CLASS_BULLSEYE) ? HasCondition( COND_SEE_ENEMY ) : FVisible( pEnemy ) )
|
||||||
|
#else
|
||||||
if ( FVisible( pEnemy ) )
|
if ( FVisible( pEnemy ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (m_flLastSeen < gpGlobals->curtime - 2)
|
if (m_flLastSeen < gpGlobals->curtime - 2)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
|
#include "ai_hint.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// memdbgon must be the last include file in a .cpp file!!!
|
// memdbgon must be the last include file in a .cpp file!!!
|
||||||
@ -561,6 +562,13 @@ private:
|
|||||||
// Death, etc.
|
// Death, etc.
|
||||||
void InputSelfDestruct( inputdata_t &inputdata );
|
void InputSelfDestruct( inputdata_t &inputdata );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// This is identical to SelfDestruct, except the helicopter won't throw out chunks while flying to a crash point.
|
||||||
|
// This input is meant to be used when the pilot is killed and there's nothing wrong with the helicopter itself.
|
||||||
|
// If there are no crash points, the helicopter will explode in place as normal.
|
||||||
|
void InputSelfDestructNoFX( inputdata_t &inputdata );
|
||||||
|
#endif
|
||||||
|
|
||||||
// Enemy visibility check
|
// Enemy visibility check
|
||||||
CBaseEntity *FindTrackBlocker( const Vector &vecViewPoint, const Vector &vecTargetPos );
|
CBaseEntity *FindTrackBlocker( const Vector &vecViewPoint, const Vector &vecTargetPos );
|
||||||
|
|
||||||
@ -584,6 +592,7 @@ private:
|
|||||||
|
|
||||||
// Various states of the helicopter firing...
|
// Various states of the helicopter firing...
|
||||||
bool PoseGunTowardTargetDirection( const Vector &vTargetDir );
|
bool PoseGunTowardTargetDirection( const Vector &vTargetDir );
|
||||||
|
float GetGunPoseSpeed() const;
|
||||||
|
|
||||||
// Compute the position to fire at (vehicle + non-vehicle case)
|
// Compute the position to fire at (vehicle + non-vehicle case)
|
||||||
void ComputeFireAtPosition( Vector *pVecActualTargetPosition );
|
void ComputeFireAtPosition( Vector *pVecActualTargetPosition );
|
||||||
@ -595,6 +604,17 @@ private:
|
|||||||
bool DoGunFiring( const Vector &vBasePos, const Vector &vGunDir, const Vector &vecFireAtPosition );
|
bool DoGunFiring( const Vector &vBasePos, const Vector &vGunDir, const Vector &vecFireAtPosition );
|
||||||
void FireElectricityGun( );
|
void FireElectricityGun( );
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
// Idle aiming
|
||||||
|
bool FindIdleAimTarget();
|
||||||
|
bool ValidIdleAimTarget( CBaseEntity *pAimTarget );
|
||||||
|
|
||||||
|
bool FValidateHintType( CAI_Hint *pHint );
|
||||||
|
|
||||||
|
inline CBaseEntity *GetIdleAimTarget() const { return m_hIdleAimTarget; }
|
||||||
|
inline void SetIdleAimTarget( CBaseEntity *pNewAimTarget ) { m_hIdleAimTarget = pNewAimTarget; }
|
||||||
|
#endif
|
||||||
|
|
||||||
// Chooses a point within the circle of death to fire in
|
// Chooses a point within the circle of death to fire in
|
||||||
void PickDirectionToCircleOfDeath( const Vector &vBasePos, const Vector &vecFireAtPosition, Vector *pResult );
|
void PickDirectionToCircleOfDeath( const Vector &vBasePos, const Vector &vecFireAtPosition, Vector *pResult );
|
||||||
|
|
||||||
@ -784,6 +804,17 @@ private:
|
|||||||
bool m_bBombsExplodeOnContact;
|
bool m_bBombsExplodeOnContact;
|
||||||
bool m_bNonCombat;
|
bool m_bNonCombat;
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
bool m_bIdleAimAround;
|
||||||
|
EHANDLE m_hIdleAimTarget;
|
||||||
|
Vector m_vecIdleAimDir;
|
||||||
|
float m_flNextIdleAimTime;
|
||||||
|
|
||||||
|
bool m_bDisableSmokeTrails;
|
||||||
|
bool m_bDisableCorpses;
|
||||||
|
bool m_bDisableExplosions;
|
||||||
|
#endif
|
||||||
|
|
||||||
int m_nNearShots;
|
int m_nNearShots;
|
||||||
int m_nMaxNearShots;
|
int m_nMaxNearShots;
|
||||||
|
|
||||||
@ -923,6 +954,15 @@ BEGIN_DATADESC( CNPC_AttackHelicopter )
|
|||||||
|
|
||||||
#ifdef MAPBASE
|
#ifdef MAPBASE
|
||||||
DEFINE_KEYFIELD( m_flFieldOfView, FIELD_FLOAT, "FieldOfView" ),
|
DEFINE_KEYFIELD( m_flFieldOfView, FIELD_FLOAT, "FieldOfView" ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_bIdleAimAround, FIELD_BOOLEAN, "IdleAimAround" ),
|
||||||
|
DEFINE_FIELD( m_hIdleAimTarget, FIELD_EHANDLE ),
|
||||||
|
DEFINE_FIELD( m_vecIdleAimDir, FIELD_VECTOR ),
|
||||||
|
DEFINE_FIELD( m_flNextIdleAimTime, FIELD_TIME ),
|
||||||
|
|
||||||
|
DEFINE_KEYFIELD( m_bDisableSmokeTrails, FIELD_BOOLEAN, "DisableSmokeTrails" ),
|
||||||
|
DEFINE_KEYFIELD( m_bDisableCorpses, FIELD_BOOLEAN, "DisableCorpses" ),
|
||||||
|
DEFINE_KEYFIELD( m_bDisableExplosions, FIELD_BOOLEAN, "DisableExplosions" ),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEFINE_FIELD( m_hCrashPoint, FIELD_EHANDLE ),
|
DEFINE_FIELD( m_hCrashPoint, FIELD_EHANDLE ),
|
||||||
@ -959,6 +999,9 @@ BEGIN_DATADESC( CNPC_AttackHelicopter )
|
|||||||
DEFINE_INPUTFUNC( FIELD_VOID, "EnablePathVisibilityTests", InputEnablePathVisibilityTests ),
|
DEFINE_INPUTFUNC( FIELD_VOID, "EnablePathVisibilityTests", InputEnablePathVisibilityTests ),
|
||||||
|
|
||||||
DEFINE_INPUTFUNC( FIELD_VOID, "SelfDestruct", InputSelfDestruct ),
|
DEFINE_INPUTFUNC( FIELD_VOID, "SelfDestruct", InputSelfDestruct ),
|
||||||
|
#ifdef MAPBASE
|
||||||
|
DEFINE_INPUTFUNC( FIELD_VOID, "SelfDestructNoFX", InputSelfDestructNoFX ),
|
||||||
|
#endif
|
||||||
|
|
||||||
DEFINE_THINKFUNC( BlinkLightsThink ),
|
DEFINE_THINKFUNC( BlinkLightsThink ),
|
||||||
DEFINE_THINKFUNC( SpotlightThink ),
|
DEFINE_THINKFUNC( SpotlightThink ),
|
||||||
@ -1709,6 +1752,21 @@ void CNPC_AttackHelicopter::InputSelfDestruct( inputdata_t &inputdata )
|
|||||||
TakeDamage( info );
|
TakeDamage( info );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
void CNPC_AttackHelicopter::InputSelfDestructNoFX( inputdata_t &inputdata )
|
||||||
|
{
|
||||||
|
m_bDisableSmokeTrails = true;
|
||||||
|
m_bDisableCorpses = true;
|
||||||
|
m_bDisableExplosions = true;
|
||||||
|
|
||||||
|
m_lifeState = LIFE_ALIVE; // Force to die properly.
|
||||||
|
CTakeDamageInfo info( this, this, Vector(0, 0, 1), WorldSpaceCenter(), GetMaxHealth(), CLASS_MISSILE );
|
||||||
|
TakeDamage( info );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// For scripted times where it *has* to shoot
|
// For scripted times where it *has* to shoot
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -2308,21 +2366,23 @@ bool CNPC_AttackHelicopter::PoseGunTowardTargetDirection( const Vector &vTargetD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float flPoseSpeed = GetGunPoseSpeed();
|
||||||
|
|
||||||
if (angles.x > m_angGun.x)
|
if (angles.x > m_angGun.x)
|
||||||
{
|
{
|
||||||
m_angGun.x = MIN( angles.x, m_angGun.x + 12 );
|
m_angGun.x = MIN( angles.x, m_angGun.x + flPoseSpeed );
|
||||||
}
|
}
|
||||||
if (angles.x < m_angGun.x)
|
if (angles.x < m_angGun.x)
|
||||||
{
|
{
|
||||||
m_angGun.x = MAX( angles.x, m_angGun.x - 12 );
|
m_angGun.x = MAX( angles.x, m_angGun.x - flPoseSpeed );
|
||||||
}
|
}
|
||||||
if (angles.y > m_angGun.y)
|
if (angles.y > m_angGun.y)
|
||||||
{
|
{
|
||||||
m_angGun.y = MIN( angles.y, m_angGun.y + 12 );
|
m_angGun.y = MIN( angles.y, m_angGun.y + flPoseSpeed );
|
||||||
}
|
}
|
||||||
if (angles.y < m_angGun.y)
|
if (angles.y < m_angGun.y)
|
||||||
{
|
{
|
||||||
m_angGun.y = MAX( angles.y, m_angGun.y - 12 );
|
m_angGun.y = MAX( angles.y, m_angGun.y - flPoseSpeed );
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPoseParameter( m_poseWeapon_Pitch, -m_angGun.x );
|
SetPoseParameter( m_poseWeapon_Pitch, -m_angGun.x );
|
||||||
@ -2332,6 +2392,20 @@ bool CNPC_AttackHelicopter::PoseGunTowardTargetDirection( const Vector &vTargetD
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Various states of the helicopter firing...
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
float CNPC_AttackHelicopter::GetGunPoseSpeed() const
|
||||||
|
{
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if (m_bIdleAimAround && !GetEnemy())
|
||||||
|
return 4.0f;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 12.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Compute the enemy position (non-vehicle case)
|
// Compute the enemy position (non-vehicle case)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -2426,6 +2500,87 @@ bool CNPC_AttackHelicopter::DoGunIdle( const Vector &vGunDir, const Vector &vTar
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Finds an idle aim target. Based on CNPC_PlayerCompanion code
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CNPC_AttackHelicopter::FindIdleAimTarget()
|
||||||
|
{
|
||||||
|
CAI_Hint *pHint;
|
||||||
|
CHintCriteria hintCriteria;
|
||||||
|
CBaseEntity *pPriorAimTarget = GetIdleAimTarget();
|
||||||
|
|
||||||
|
hintCriteria.SetHintType( HINT_WORLD_VISUALLY_INTERESTING );
|
||||||
|
hintCriteria.SetFlag( bits_HINT_NODE_VISIBLE | bits_HINT_NODE_IN_VIEWCONE | bits_HINT_NPC_IN_NODE_FOV | bits_HINT_NODE_USE_GROUP | bits_HINT_NODE_NEAREST );
|
||||||
|
hintCriteria.AddIncludePosition( GetAbsOrigin(), CHOPPER_MAX_GUN_DIST );
|
||||||
|
pHint = CAI_HintManager::FindHint( this, hintCriteria );
|
||||||
|
|
||||||
|
if( pHint )
|
||||||
|
{
|
||||||
|
if ( !ValidIdleAimTarget( pHint ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( pHint != pPriorAimTarget )
|
||||||
|
{
|
||||||
|
// Notify of the change.
|
||||||
|
SetIdleAimTarget( pHint );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't find an aim target, or found the same one.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Finds an idle aim target. Based on CNPC_PlayerCompanion code
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CNPC_AttackHelicopter::ValidIdleAimTarget( CBaseEntity *pAimTarget )
|
||||||
|
{
|
||||||
|
Vector vecTargetOrigin = pAimTarget->GetAbsOrigin();
|
||||||
|
|
||||||
|
Vector vBasePos;
|
||||||
|
GetAttachment( m_nGunBaseAttachment, vBasePos );
|
||||||
|
|
||||||
|
if ( vecTargetOrigin.z > vBasePos.z || (vecTargetOrigin - vBasePos).Length() < 128.0f )
|
||||||
|
{
|
||||||
|
// Too close!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_t tr;
|
||||||
|
UTIL_TraceLine( vBasePos, vecTargetOrigin, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr );
|
||||||
|
|
||||||
|
if ( tr.fraction < 1.0f && tr.m_pEnt != pAimTarget )
|
||||||
|
{
|
||||||
|
// No LOS
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool CNPC_AttackHelicopter::FValidateHintType( CAI_Hint *pHint )
|
||||||
|
{
|
||||||
|
switch( pHint->HintType() )
|
||||||
|
{
|
||||||
|
case HINT_WORLD_VISUALLY_INTERESTING:
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BaseClass::FValidateHintType( pHint );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// How easy is the target to hit?
|
// How easy is the target to hit?
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -3716,12 +3871,20 @@ int CNPC_AttackHelicopter::OnTakeDamage_Alive( const CTakeDamageInfo &info )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_SMOKE_TRAILS ) && !m_bDisableSmokeTrails )
|
||||||
|
#else
|
||||||
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_SMOKE_TRAILS ) )
|
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_SMOKE_TRAILS ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
AddSmokeTrail( info.GetDamagePosition() );
|
AddSmokeTrail( info.GetDamagePosition() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_CORPSES ) && !m_bDisableCorpses )
|
||||||
|
#else
|
||||||
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_CORPSES ) )
|
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_CORPSES ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if ( nPrevHealth != GetMaxHealth() )
|
if ( nPrevHealth != GetMaxHealth() )
|
||||||
{
|
{
|
||||||
@ -3729,7 +3892,11 @@ int CNPC_AttackHelicopter::OnTakeDamage_Alive( const CTakeDamageInfo &info )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_EXPLOSIONS ) && !m_bDisableExplosions )
|
||||||
|
#else
|
||||||
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_EXPLOSIONS ) )
|
if ( ShouldTriggerDamageEffect( nPrevHealth, MAX_EXPLOSIONS ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
ExplodeAndThrowChunk( info.GetDamagePosition() );
|
ExplodeAndThrowChunk( info.GetDamagePosition() );
|
||||||
}
|
}
|
||||||
@ -3978,7 +4145,11 @@ void CNPC_AttackHelicopter::PrescheduleThink( void )
|
|||||||
SetDesiredPosition( GetCrashPoint()->WorldSpaceCenter() );
|
SetDesiredPosition( GetCrashPoint()->WorldSpaceCenter() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if ( !m_bDisableExplosions && random->RandomInt( 0, 4 ) == 0 )
|
||||||
|
#else
|
||||||
if ( random->RandomInt( 0, 4 ) == 0 )
|
if ( random->RandomInt( 0, 4 ) == 0 )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
Vector explodePoint;
|
Vector explodePoint;
|
||||||
CollisionProp()->RandomPointInBounds( Vector(0.25,0.25,0.25), Vector(0.75,0.75,0.75), &explodePoint );
|
CollisionProp()->RandomPointInBounds( Vector(0.25,0.25,0.25), Vector(0.75,0.75,0.75), &explodePoint );
|
||||||
@ -5003,6 +5174,55 @@ void CNPC_AttackHelicopter::Hunt( void )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MAPBASE
|
||||||
|
if (m_bIdleAimAround)
|
||||||
|
{
|
||||||
|
if (!GetEnemy())
|
||||||
|
{
|
||||||
|
if (GetIdleAimTarget())
|
||||||
|
{
|
||||||
|
if (!ValidIdleAimTarget( GetIdleAimTarget() ))
|
||||||
|
{
|
||||||
|
SetIdleAimTarget( NULL );
|
||||||
|
m_flNextIdleAimTime = gpGlobals->curtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_flNextIdleAimTime < gpGlobals->curtime)
|
||||||
|
{
|
||||||
|
if (!FindIdleAimTarget())
|
||||||
|
{
|
||||||
|
SetIdleAimTarget( NULL );
|
||||||
|
|
||||||
|
// Find a random direction in front of us instead
|
||||||
|
Vector vBasePos, vecForward, vecRight, vecUp;
|
||||||
|
GetAttachment( m_nGunBaseAttachment, vBasePos, &vecForward, &vecRight, &vecUp );
|
||||||
|
|
||||||
|
m_vecIdleAimDir = vecForward + (vecRight * RandomFloat( -0.25f, 0.25f )) + (vecUp * RandomFloat( -0.8f, -0.25f ));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_flNextIdleAimTime = gpGlobals->curtime + RandomFloat( 4.0f, 6.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetIdleAimTarget())
|
||||||
|
{
|
||||||
|
// Get gun attachment points
|
||||||
|
Vector vBasePos;
|
||||||
|
GetAttachment( m_nGunBaseAttachment, vBasePos );
|
||||||
|
|
||||||
|
m_vecIdleAimDir = GetIdleAimTarget()->GetAbsOrigin() - vBasePos;
|
||||||
|
VectorNormalize( m_vecIdleAimDir );
|
||||||
|
}
|
||||||
|
|
||||||
|
PoseGunTowardTargetDirection( m_vecIdleAimDir );
|
||||||
|
}
|
||||||
|
else if (GetIdleAimTarget())
|
||||||
|
{
|
||||||
|
SetIdleAimTarget( NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HL2_EPISODIC
|
#ifdef HL2_EPISODIC
|
||||||
// Update our bone followers
|
// Update our bone followers
|
||||||
m_BoneFollowerManager.UpdateBoneFollowers(this);
|
m_BoneFollowerManager.UpdateBoneFollowers(this);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user