mirror of
https://github.com/mapbase-source/source-sdk-2013.git
synced 2024-12-26 06:45:31 +03:00
Integrated medium cover activities into standoffs and beyond
This commit is contained in:
parent
833f0b0823
commit
26c05ee685
@ -6509,7 +6509,7 @@ CAI_BaseNPC *CAI_BaseNPC::CreateCustomTarget( const Vector &vecOrigin, float dur
|
||||
//-----------------------------------------------------------------------------
|
||||
Activity CAI_BaseNPC::TranslateCrouchActivity( Activity eNewActivity )
|
||||
{
|
||||
if (CapabilitiesGet() & bits_CAP_DUCK)
|
||||
if (CapabilitiesGet() & bits_CAP_DUCK && CanTranslateCrouchActivity())
|
||||
{
|
||||
// ========================================================================
|
||||
// The main issue with cover hint nodes is that crouch activities are not translated at the right time
|
||||
@ -6541,10 +6541,18 @@ Activity CAI_BaseNPC::TranslateCrouchActivity( Activity eNewActivity )
|
||||
CAI_Hint *pHint = GetHintNode();
|
||||
if (pHint)
|
||||
{
|
||||
if (pHint->HintType() == HINT_TACTICAL_COVER_LOW || pHint->HintType() == HINT_TACTICAL_COVER_MED)
|
||||
if (pHint->HintType() == HINT_TACTICAL_COVER_LOW)
|
||||
{
|
||||
nCoverActivity = ACT_RANGE_ATTACK1_LOW;
|
||||
}
|
||||
else if (pHint->HintType() == HINT_TACTICAL_COVER_MED)
|
||||
{
|
||||
#ifdef EXPANDED_HL2_COVER_ACTIVITIES
|
||||
nCoverActivity = ACT_RANGE_ATTACK1_MED;
|
||||
#else
|
||||
nCoverActivity = ACT_RANGE_ATTACK1_LOW;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6586,21 +6594,30 @@ Activity CAI_BaseNPC::NPC_BackupActivity( Activity eNewActivity )
|
||||
//if (eNewActivity == ACT_DROP_WEAPON)
|
||||
// return TranslateActivity(ACT_IDLE);
|
||||
|
||||
// ---------------------------------------------
|
||||
|
||||
// Accounts for certain act busy activities that aren't on all NPCs.
|
||||
if (eNewActivity == ACT_BUSY_QUEUE || eNewActivity == ACT_BUSY_STAND)
|
||||
return TranslateActivity(ACT_IDLE);
|
||||
|
||||
// ---------------------------------------------
|
||||
|
||||
if (eNewActivity == ACT_WALK_ANGRY)
|
||||
return TranslateActivity(ACT_WALK);
|
||||
|
||||
// ---------------------------------------------
|
||||
|
||||
// If one climbing animation isn't available, use the other
|
||||
if (eNewActivity == ACT_CLIMB_DOWN)
|
||||
return ACT_CLIMB_UP;
|
||||
else if (eNewActivity == ACT_CLIMB_UP)
|
||||
return ACT_CLIMB_DOWN;
|
||||
|
||||
// GetCoverActivity() should have this covered.
|
||||
// ---------------------------------------------
|
||||
|
||||
if (eNewActivity == ACT_COVER_MED)
|
||||
eNewActivity = ACT_COVER_LOW;
|
||||
|
||||
//if (eNewActivity == ACT_COVER)
|
||||
// return TranslateActivity(ACT_IDLE);
|
||||
|
||||
@ -9137,27 +9154,45 @@ Activity CAI_BaseNPC::GetCoverActivity( CAI_Hint *pHint )
|
||||
switch (pHint->HintType())
|
||||
{
|
||||
case HINT_TACTICAL_COVER_MED:
|
||||
#ifndef MAPBASE // I know what you're thinking, but ACT_COVER_MED is pretty much deprecated at this point anyway.
|
||||
{
|
||||
nCoverActivity = ACT_COVER_MED;
|
||||
#ifdef MAPBASE
|
||||
// Some NPCs lack ACT_COVER_MED, but could easily use ACT_COVER_LOW.
|
||||
if (SelectWeightedSequence(nCoverActivity) == ACTIVITY_NOT_AVAILABLE)
|
||||
nCoverActivity = ACT_COVER_LOW;
|
||||
#endif
|
||||
// NPCs which lack ACT_COVER_MED should fall through to HINT_TACTICAL_COVER_LOW
|
||||
if (SelectWeightedSequence( ACT_COVER_MED ) != ACTIVITY_NOT_AVAILABLE)
|
||||
{
|
||||
nCoverActivity = ACT_COVER_MED;
|
||||
}
|
||||
#else
|
||||
nCoverActivity = ACT_COVER_MED;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
case HINT_TACTICAL_COVER_LOW:
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if (pHint->HintActivityName() != NULL_STRING)
|
||||
nCoverActivity = (Activity)CAI_BaseNPC::GetActivityID( STRING(pHint->HintActivityName()) );
|
||||
else
|
||||
#endif
|
||||
// Make sure nCoverActivity wasn't already assigned above, then fall through to HINT_TACTICAL_COVER_CUSTOM
|
||||
if (nCoverActivity == ACT_INVALID)
|
||||
nCoverActivity = ACT_COVER_LOW;
|
||||
#else
|
||||
nCoverActivity = ACT_COVER_LOW;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
case HINT_TACTICAL_COVER_CUSTOM:
|
||||
{
|
||||
if (pHint->HintActivityName() != NULL_STRING)
|
||||
{
|
||||
nCoverActivity = (Activity)CAI_BaseNPC::GetActivityID( STRING(pHint->HintActivityName()) );
|
||||
if (nCoverActivity == ACT_INVALID)
|
||||
{
|
||||
m_iszSceneCustomMoveSeq = pHint->HintActivityName();
|
||||
nCoverActivity = ACT_SCRIPT_CUSTOM_MOVE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -15985,6 +16020,26 @@ bool CAI_BaseNPC::CouldShootIfCrouching( CBaseEntity *pTarget )
|
||||
return bResult;
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Check if this position will block our line of sight if aiming low.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CAI_BaseNPC::CouldShootIfCrouchingAt( const Vector &vecPosition, const Vector &vecForward, const Vector &vecRight, float flDist )
|
||||
{
|
||||
Vector vGunPos = vecPosition;
|
||||
vGunPos += (GetCrouchGunOffset() + vecRight * 8);
|
||||
|
||||
trace_t tr;
|
||||
AI_TraceLOS( vGunPos, vGunPos + (vecForward * flDist), this, &tr );
|
||||
if (tr.fraction != 1.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -998,6 +998,7 @@ public:
|
||||
Activity NPC_TranslateActivity( Activity eNewActivity );
|
||||
#ifdef MAPBASE
|
||||
Activity TranslateCrouchActivity( Activity baseAct );
|
||||
virtual bool CanTranslateCrouchActivity( void ) { return true; }
|
||||
virtual Activity NPC_BackupActivity( Activity eNewActivity );
|
||||
#endif
|
||||
Activity GetActivity( void ) { return m_Activity; }
|
||||
@ -2207,6 +2208,10 @@ public:
|
||||
inline void ForceCrouch( void );
|
||||
inline void ClearForceCrouch( void );
|
||||
|
||||
#ifdef MAPBASE
|
||||
bool CouldShootIfCrouchingAt( const Vector &vecPosition, const Vector &vecForward, const Vector &vecRight, float flDist = 48.0f );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual bool Crouch( void );
|
||||
virtual bool Stand( void );
|
||||
|
@ -420,6 +420,24 @@ bool CAI_BehaviorBase::CanUnholsterWeapon( void )
|
||||
|
||||
return m_pBackBridge->BackBridge_CanUnholsterWeapon();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
bool CAI_BehaviorBase::ShouldPickADeathPose( void )
|
||||
{
|
||||
Assert( m_pBackBridge != NULL );
|
||||
|
||||
return m_pBackBridge->BackBridge_ShouldPickADeathPose();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
bool CAI_BehaviorBase::CanTranslateCrouchActivity( void )
|
||||
{
|
||||
Assert( m_pBackBridge != NULL );
|
||||
|
||||
return m_pBackBridge->BackBridge_CanTranslateCrouchActivity();
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -132,6 +132,8 @@ public:
|
||||
void BridgeHandleAnimEvent( animevent_t *pEvent );
|
||||
#ifdef MAPBASE
|
||||
bool BridgeCanUnholsterWeapon( void );
|
||||
bool BridgeShouldPickADeathPose( void );
|
||||
bool BridgeCanTranslateCrouchActivity( void );
|
||||
#endif
|
||||
|
||||
virtual void GatherConditions();
|
||||
@ -220,6 +222,8 @@ protected:
|
||||
virtual void HandleAnimEvent( animevent_t *pEvent );
|
||||
#ifdef MAPBASE
|
||||
virtual bool CanUnholsterWeapon( void );
|
||||
virtual bool ShouldPickADeathPose( void );
|
||||
virtual bool CanTranslateCrouchActivity( void );
|
||||
#endif
|
||||
|
||||
virtual bool ShouldAlwaysThink();
|
||||
@ -370,6 +374,9 @@ public:
|
||||
#ifdef MAPBASE
|
||||
// For func_tank behavior
|
||||
virtual bool BackBridge_CanUnholsterWeapon( void ) = 0;
|
||||
|
||||
virtual bool BackBridge_ShouldPickADeathPose( void ) = 0;
|
||||
virtual bool BackBridge_CanTranslateCrouchActivity( void ) = 0;
|
||||
#endif
|
||||
|
||||
//-------------------------------------
|
||||
@ -470,6 +477,8 @@ public:
|
||||
void HandleAnimEvent( animevent_t *pEvent );
|
||||
#ifdef MAPBASE
|
||||
bool CanUnholsterWeapon( void );
|
||||
bool ShouldPickADeathPose( void );
|
||||
bool CanTranslateCrouchActivity( void );
|
||||
#endif
|
||||
|
||||
bool ShouldAlwaysThink();
|
||||
@ -534,6 +543,9 @@ private:
|
||||
#ifdef MAPBASE
|
||||
// For func_tank behavior
|
||||
bool BackBridge_CanUnholsterWeapon( void );
|
||||
|
||||
bool BackBridge_ShouldPickADeathPose( void );
|
||||
bool BackBridge_CanTranslateCrouchActivity( void );
|
||||
#endif
|
||||
|
||||
CAI_BehaviorBase **AccessBehaviors();
|
||||
@ -913,6 +925,20 @@ inline bool CAI_BehaviorBase::BridgeCanUnholsterWeapon( void )
|
||||
{
|
||||
return CanUnholsterWeapon();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline bool CAI_BehaviorBase::BridgeShouldPickADeathPose( void )
|
||||
{
|
||||
return ShouldPickADeathPose();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline bool CAI_BehaviorBase::BridgeCanTranslateCrouchActivity( void )
|
||||
{
|
||||
return CanTranslateCrouchActivity();
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1498,6 +1524,22 @@ inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_CanUnholsterWeapon( void )
|
||||
{
|
||||
return BaseClass::CanUnholsterWeapon();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
template <class BASE_NPC>
|
||||
inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_ShouldPickADeathPose( void )
|
||||
{
|
||||
return BaseClass::ShouldPickADeathPose();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
template <class BASE_NPC>
|
||||
inline bool CAI_BehaviorHost<BASE_NPC>::BackBridge_CanTranslateCrouchActivity( void )
|
||||
{
|
||||
return BaseClass::CanTranslateCrouchActivity();
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------
|
||||
@ -1914,6 +1956,28 @@ inline bool CAI_BehaviorHost<BASE_NPC>::CanUnholsterWeapon( void )
|
||||
|
||||
return BaseClass::CanUnholsterWeapon();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
template <class BASE_NPC>
|
||||
inline bool CAI_BehaviorHost<BASE_NPC>::ShouldPickADeathPose( void )
|
||||
{
|
||||
if (m_pCurBehavior)
|
||||
return m_pCurBehavior->BridgeShouldPickADeathPose();
|
||||
|
||||
return BaseClass::ShouldPickADeathPose();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
template <class BASE_NPC>
|
||||
inline bool CAI_BehaviorHost<BASE_NPC>::CanTranslateCrouchActivity( void )
|
||||
{
|
||||
if (m_pCurBehavior)
|
||||
return m_pCurBehavior->BridgeCanTranslateCrouchActivity();
|
||||
|
||||
return BaseClass::CanTranslateCrouchActivity();
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -535,10 +535,11 @@ int CAI_StandoffBehavior::SelectScheduleCheckCover( void )
|
||||
{
|
||||
StandoffMsg( "Regulated to not shoot\n" );
|
||||
#ifdef MAPBASE
|
||||
if ( GetHintType() == HINT_TACTICAL_COVER_LOW || GetHintType() == HINT_TACTICAL_COVER_MED )
|
||||
#else
|
||||
if ( GetHintType() == HINT_TACTICAL_COVER_LOW )
|
||||
if ( GetHintType() == HINT_TACTICAL_COVER_MED || GetCoverActivity() == ACT_COVER_MED )
|
||||
SetPosture( AIP_CROUCHING_MED );
|
||||
else
|
||||
#endif
|
||||
if ( GetHintType() == HINT_TACTICAL_COVER_LOW )
|
||||
SetPosture( AIP_CROUCHING );
|
||||
else
|
||||
SetPosture( AIP_STANDING );
|
||||
@ -557,7 +558,11 @@ int CAI_StandoffBehavior::SelectScheduleEstablishAim( void )
|
||||
{
|
||||
if ( HasCondition( COND_ENEMY_OCCLUDED ) )
|
||||
{
|
||||
#ifdef EXPANDED_HL2_COVER_ACTIVITIES
|
||||
if ( GetPosture() == AIP_CROUCHING || GetPosture() == AIP_CROUCHING_MED )
|
||||
#else
|
||||
if ( GetPosture() == AIP_CROUCHING )
|
||||
#endif
|
||||
{
|
||||
// force a stand up, just in case
|
||||
GetOuter()->SpeakSentence( STANDOFF_SENTENCE_STAND_CHECK_TARGET );
|
||||
@ -668,6 +673,15 @@ Activity CAI_MappedActivityBehavior_Temporary::GetMappedActivity( AI_Posture_t p
|
||||
{
|
||||
if ( posture != AIP_STANDING )
|
||||
{
|
||||
#ifdef EXPANDED_HL2_COVER_ACTIVITIES
|
||||
// See UpdateTranslateActivityMap() for more information on what this is for
|
||||
if ( posture == AIP_CROUCHING_MED )
|
||||
{
|
||||
if (activity != ACT_RANGE_ATTACK1)
|
||||
posture = AIP_CROUCHING;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned short iActivityTranslation = m_ActivityMap.Find( MAKE_ACTMAP_KEY( posture, activity ) );
|
||||
if ( iActivityTranslation != m_ActivityMap.InvalidIndex() )
|
||||
{
|
||||
@ -685,10 +699,28 @@ Activity CAI_StandoffBehavior::NPC_TranslateActivity( Activity activity )
|
||||
Activity coverActivity = GetCoverActivity();
|
||||
if ( coverActivity != ACT_INVALID )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if ( GetPosture() == AIP_STANDING )
|
||||
{
|
||||
if ( coverActivity == ACT_COVER_LOW )
|
||||
SetPosture( AIP_CROUCHING );
|
||||
else if ( coverActivity == ACT_COVER_MED )
|
||||
{
|
||||
SetPosture( AIP_CROUCHING_MED );
|
||||
coverActivity = ACT_COVER_LOW;
|
||||
}
|
||||
}
|
||||
else if (coverActivity == ACT_COVER_MED)
|
||||
coverActivity = ACT_COVER_LOW;
|
||||
|
||||
if ( activity == ACT_IDLE )
|
||||
activity = coverActivity;
|
||||
#else
|
||||
if (activity == ACT_IDLE)
|
||||
activity = coverActivity;
|
||||
if ( GetPosture() == AIP_STANDING && coverActivity == ACT_COVER_LOW )
|
||||
SetPosture( AIP_CROUCHING );
|
||||
#endif
|
||||
}
|
||||
|
||||
Activity result = GetMappedActivity( GetPosture(), activity );
|
||||
@ -1089,12 +1121,25 @@ void CAI_StandoffBehavior::UnlockHintNode()
|
||||
|
||||
Activity CAI_StandoffBehavior::GetCoverActivity()
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
// This does two things:
|
||||
// A. Allows medium cover nodes to be used, kind of.
|
||||
// B. GetCoverActivity() already checks everything we checked here.
|
||||
Activity coveract = GetOuter()->GetCoverActivity( GetHintNode() );
|
||||
return coveract == ACT_IDLE ? ACT_INVALID : coveract;
|
||||
#ifdef EXPANDED_HL2_COVER_ACTIVITIES
|
||||
// GetCoverActivity() already checks everything we checked here.
|
||||
Activity coverActivity = GetOuter()->GetCoverActivity( GetHintNode() );
|
||||
|
||||
if (coverActivity == ACT_COVER_LOW)
|
||||
{
|
||||
// Check if this node will block our line of sight if aiming low.
|
||||
Vector vHintPos, vHintForward, vHintRight;
|
||||
GetHintNode()->GetPosition( GetHullType(), &vHintPos );
|
||||
vHintForward = GetHintNode()->GetDirection();
|
||||
|
||||
GetHintNode()->GetVectors( NULL, &vHintRight, NULL );
|
||||
if (GetOuter()->CouldShootIfCrouchingAt( vHintPos, vHintForward, vHintRight ))
|
||||
{
|
||||
coverActivity = ACT_COVER_MED;
|
||||
}
|
||||
}
|
||||
|
||||
return coverActivity == ACT_IDLE ? ACT_INVALID : coverActivity;
|
||||
#else
|
||||
CAI_Hint *pHintNode = GetHintNode();
|
||||
if ( pHintNode && pHintNode->HintType() == HINT_TACTICAL_COVER_LOW )
|
||||
@ -1112,6 +1157,14 @@ struct AI_ActivityMapping_t
|
||||
Activity activity;
|
||||
const char * pszWeapon;
|
||||
Activity translation;
|
||||
#ifdef MAPBASE
|
||||
Activity backup;
|
||||
|
||||
AI_ActivityMapping_t( AI_Posture_t _p, Activity _a, const char *_w, Activity _t, Activity _b = ACT_INVALID )
|
||||
{
|
||||
posture = _p; activity = _a; pszWeapon = _w; translation = _t; backup = _b;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void CAI_MappedActivityBehavior_Temporary::UpdateTranslateActivityMap()
|
||||
@ -1125,15 +1178,60 @@ void CAI_MappedActivityBehavior_Temporary::UpdateTranslateActivityMap()
|
||||
{ AIP_CROUCHING, ACT_WALK_AIM, NULL, ACT_WALK_CROUCH_AIM, },
|
||||
{ AIP_CROUCHING, ACT_RUN_AIM, NULL, ACT_RUN_CROUCH_AIM, },
|
||||
{ AIP_CROUCHING, ACT_RELOAD, NULL, ACT_RELOAD_LOW, },
|
||||
#ifdef MAPBASE
|
||||
{ AIP_CROUCHING, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_LOW, },
|
||||
{ AIP_CROUCHING, ACT_COVER_MED, NULL, ACT_COVER_LOW, },
|
||||
#else
|
||||
{ AIP_CROUCHING, ACT_RANGE_ATTACK_SMG1, NULL, ACT_RANGE_ATTACK_SMG1_LOW, },
|
||||
{ AIP_CROUCHING, ACT_RANGE_ATTACK_AR2, NULL, ACT_RANGE_ATTACK_AR2_LOW, },
|
||||
#endif
|
||||
|
||||
#ifdef EXPANDED_HL2_COVER_ACTIVITIES
|
||||
//
|
||||
// ============ Really long explanation that should be in a wiki/documentation article somewhere ~ Blixibon, 10/27/2021 ============
|
||||
//
|
||||
// Standoff behavior assumes low attack animations allow NPCs to see over barricades, with ACT_COVER_LOW being their "safely in cover" animation.
|
||||
// This is why AIP_CROUCHING translates ACT_RANGE_ATTACK1 to its low animation, but translates ACT_IDLE_ANGRY to ACT_COVER_LOW instead of ACT_RANGE_AIM_LOW,
|
||||
// as this would ideally allow NPCs to pop in and out of cover to shoot.
|
||||
// This is also why AIP_PEEKING translates ACT_COVER_LOW to ACT_RANGE_AIM_LOW, as it's supposed to force the NPC to peek over their cover.
|
||||
//
|
||||
// However, this assumption mainly just applies to metrocops. Citizens' low attacking animations crouch low to the ground (which isn't effective for
|
||||
// shooting over most barricades) and, while they do have a distinct ACT_COVER_LOW animation with transitions, they are close enough together that popping
|
||||
// in and out of cover is redundant in most cases. Meanwhile, Combine soldiers have identical ACT_COVER_LOW and ACT_RANGE_AIM_LOW animations, which means
|
||||
// they do not pop in and out of cover and AIP_PEEKING does nothing. This may be the reason why Combine soldiers occasionally get stuck in cover after a fight.
|
||||
//
|
||||
// -------------------------------------------------------------
|
||||
//
|
||||
// As part of Mapbase v7.0's NPC activity overhaul, a new "medium cover" activity set has been added. Metrocops' previous "low cover" animation set (which, as
|
||||
// mentioned before, is different from that of other NPCs) has been retroactively changed to use "medium cover". This was done for a few reasons unrelated to
|
||||
// standoff behavior, but the important point is that these activities indicate a new cover height. This means we can use them to give standoff behavior more leeway
|
||||
// for judging which animations to use in various levels of cover.
|
||||
//
|
||||
// Standoff behavior can use "medium cover" animations in cover which is too high for the "low" animations, and when the medium cover animations are not available,
|
||||
// it simply falls back to the "standing" animations, thus resolving the issue with other NPCs not peeking in and out of cover without requiring new medium cover
|
||||
// animations.
|
||||
//
|
||||
// In Mapbase, this is done by changing AIP_PEEKING to use the medium cover animations and adding a new alternate crouching posture posture called "AIP_CROUCHING_MED",
|
||||
// which only uses the medium cover attack activity and otherwise automatically falls back to AIP_CROUCHING. AIP_CROUCHING_MED is automatically set if the NPC cannot
|
||||
// get LOS from a regular crouching position.
|
||||
//
|
||||
{ AIP_CROUCHING_MED, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_MED, },
|
||||
|
||||
//----
|
||||
{ AIP_PEEKING, ACT_IDLE, NULL, ACT_RANGE_AIM_MED, },
|
||||
{ AIP_PEEKING, ACT_IDLE_ANGRY, NULL, ACT_RANGE_AIM_MED, },
|
||||
{ AIP_PEEKING, ACT_COVER_LOW, NULL, ACT_RANGE_AIM_MED, ACT_IDLE_ANGRY },
|
||||
{ AIP_PEEKING, ACT_COVER_MED, NULL, ACT_RANGE_AIM_MED, ACT_IDLE_ANGRY },
|
||||
{ AIP_PEEKING, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_MED, },
|
||||
{ AIP_PEEKING, ACT_RELOAD, NULL, ACT_RELOAD_LOW, },
|
||||
#else
|
||||
//----
|
||||
{ AIP_PEEKING, ACT_IDLE, NULL, ACT_RANGE_AIM_LOW, },
|
||||
{ AIP_PEEKING, ACT_IDLE_ANGRY, NULL, ACT_RANGE_AIM_LOW, },
|
||||
{ AIP_PEEKING, ACT_COVER_LOW, NULL, ACT_RANGE_AIM_LOW, },
|
||||
{ AIP_PEEKING, ACT_RANGE_ATTACK1, NULL, ACT_RANGE_ATTACK1_LOW, },
|
||||
{ AIP_PEEKING, ACT_RELOAD, NULL, ACT_RELOAD_LOW, },
|
||||
#endif
|
||||
};
|
||||
|
||||
m_ActivityMap.RemoveAll();
|
||||
@ -1145,7 +1243,7 @@ void CAI_MappedActivityBehavior_Temporary::UpdateTranslateActivityMap()
|
||||
if ( !mappings[i].pszWeapon || stricmp( mappings[i].pszWeapon, pszWeaponClass ) == 0 )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
// Check backup activity
|
||||
// Check NPC backup activity
|
||||
if ( HaveSequenceForActivity( mappings[i].translation ) || HaveSequenceForActivity( GetOuter()->Weapon_TranslateActivity( mappings[i].translation ) ) || HaveSequenceForActivity( GetOuter()->Weapon_BackupActivity( mappings[i].translation ) ) )
|
||||
#else
|
||||
if ( HaveSequenceForActivity( mappings[i].translation ) || HaveSequenceForActivity( GetOuter()->Weapon_TranslateActivity( mappings[i].translation ) ) )
|
||||
@ -1154,6 +1252,14 @@ void CAI_MappedActivityBehavior_Temporary::UpdateTranslateActivityMap()
|
||||
Assert( m_ActivityMap.Find( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ) ) == m_ActivityMap.InvalidIndex() );
|
||||
m_ActivityMap.Insert( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ), mappings[i].translation );
|
||||
}
|
||||
#ifdef MAPBASE
|
||||
// Check activity map backup activity
|
||||
else if ( mappings[i].backup != ACT_INVALID && HaveSequenceForActivity( mappings[i].backup ) )
|
||||
{
|
||||
Assert( m_ActivityMap.Find( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ) ) == m_ActivityMap.InvalidIndex() );
|
||||
m_ActivityMap.Insert( MAKE_ACTMAP_KEY( mappings[i].posture, mappings[i].activity ), mappings[i].backup );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,9 @@ enum AI_Posture_t
|
||||
AIP_INDIFFERENT,
|
||||
AIP_STANDING,
|
||||
AIP_CROUCHING,
|
||||
#ifdef EXPANDED_HL2_COVER_ACTIVITIES
|
||||
AIP_CROUCHING_MED, // See UpdateTranslateActivityMap() for more information on what this is for
|
||||
#endif
|
||||
AIP_PEEKING,
|
||||
};
|
||||
|
||||
@ -150,6 +153,14 @@ protected:
|
||||
// Standoff overrides base AI crouch handling
|
||||
bool IsCrouching( void ) { return false; }
|
||||
|
||||
#ifdef MAPBASE
|
||||
// Standoff overrides base cover activity translation
|
||||
bool CanTranslateCrouchActivity( void ) { return false; }
|
||||
|
||||
// Don't do death poses while crouching
|
||||
bool ShouldPickADeathPose( void ) { return (GetPosture() != AIP_CROUCHING && GetPosture() != AIP_PEEKING) && BaseClass::ShouldPickADeathPose(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
//----------------------------
|
||||
|
@ -4536,34 +4536,7 @@ int CNPC_MetroPolice::SelectBehaviorOverrideSchedule()
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CNPC_MetroPolice::IsCrouchedActivity( Activity activity )
|
||||
{
|
||||
Activity realActivity = TranslateActivity(activity);
|
||||
|
||||
switch ( realActivity )
|
||||
{
|
||||
case ACT_RELOAD_LOW:
|
||||
case ACT_COVER_LOW:
|
||||
case ACT_COVER_PISTOL_LOW:
|
||||
case ACT_COVER_SMG1_LOW:
|
||||
case ACT_RELOAD_SMG1_LOW:
|
||||
//case ACT_RELOAD_AR2_LOW:
|
||||
case ACT_RELOAD_PISTOL_LOW:
|
||||
case ACT_RELOAD_SHOTGUN_LOW:
|
||||
|
||||
// These animations aren't actually "low" on metrocops
|
||||
//case ACT_RANGE_AIM_LOW:
|
||||
//case ACT_RANGE_AIM_AR2_LOW:
|
||||
//case ACT_RANGE_AIM_SMG1_LOW:
|
||||
//case ACT_RANGE_AIM_PISTOL_LOW:
|
||||
|
||||
//case ACT_RANGE_ATTACK1_LOW:
|
||||
//case ACT_RANGE_ATTACK_AR2_LOW:
|
||||
//case ACT_RANGE_ATTACK_SMG1_LOW:
|
||||
//case ACT_RANGE_ATTACK_PISTOL_LOW:
|
||||
//case ACT_RANGE_ATTACK2_LOW:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return BaseClass::IsCrouchedActivity( activity );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user