Integrated custom cover hints into base AI movement code

This commit is contained in:
Blixibon 2021-10-27 23:59:27 -05:00
parent dfa7e6c0c2
commit ece1a612ce
8 changed files with 96 additions and 13 deletions

View File

@ -1095,9 +1095,9 @@ void CBaseAnimatingOverlay::SetLayerNoRestore( int iLayer, bool bNoRestore )
}
#ifdef MAPBASE // From Alien Swarm SDK
#ifdef MAPBASE
//-----------------------------------------------------------------------------
// Purpose:
// From Alien Swarm SDK
//-----------------------------------------------------------------------------
void CBaseAnimatingOverlay::SetLayerNoEvents( int iLayer, bool bNoEvents )
{
@ -1113,6 +1113,17 @@ void CBaseAnimatingOverlay::SetLayerNoEvents( int iLayer, bool bNoEvents )
m_AnimOverlay[iLayer].m_fFlags &= ~ANIM_LAYER_NOEVENTS;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseAnimatingOverlay::IsLayerFinished( int iLayer )
{
if (!IsValidLayer( iLayer ))
return true;
return m_AnimOverlay[iLayer].m_bSequenceFinished;
}
#endif

View File

@ -181,8 +181,10 @@ public:
void SetLayerAutokill( int iLayer, bool bAutokill );
void SetLayerLooping( int iLayer, bool bLooping );
void SetLayerNoRestore( int iLayer, bool bNoRestore );
#ifdef MAPBASE // From Alien Swarm SDK
void SetLayerNoEvents( int iLayer, bool bNoEvents );
#ifdef MAPBASE
void SetLayerNoEvents( int iLayer, bool bNoEvents ); // From Alien Swarm SDK
bool IsLayerFinished( int iLayer );
#endif
Activity GetLayerActivity( int iLayer );

View File

@ -2598,7 +2598,11 @@ bool CAI_BaseNPC::FValidateHintType ( CAI_Hint *pHint )
Activity CAI_BaseNPC::GetHintActivity( short sHintType, Activity HintsActivity )
{
if ( HintsActivity != ACT_INVALID )
#ifdef MAPBASE
return TranslateActivity( HintsActivity ); // Always translate the activity
#else
return HintsActivity;
#endif
return ACT_IDLE;
}
@ -6866,7 +6870,12 @@ void CAI_BaseNPC::ResolveActivityToSequence(Activity NewActivity, int &iSequence
translatedActivity = TranslateActivity( NewActivity, &weaponActivity );
#ifdef MAPBASE
// Cover cases where TranslateActivity() returns a sequence by using ACT_SCRIPT_CUSTOM_MOVE
if ( NewActivity == ACT_SCRIPT_CUSTOM_MOVE || translatedActivity == ACT_SCRIPT_CUSTOM_MOVE )
#else
if ( NewActivity == ACT_SCRIPT_CUSTOM_MOVE )
#endif
{
iSequence = GetScriptCustomMoveSequence();
}
@ -7339,6 +7348,15 @@ void CAI_BaseNPC::OnChangeActivity( Activity eNewActivity )
eNewActivity == ACT_WALK )
{
Stand();
#ifdef MAPBASE
// Unlock custom cover nodes
if (GetHintNode() && GetHintNode()->HintType() == HINT_TACTICAL_COVER_CUSTOM && HasMemory(bits_MEMORY_INCOVER))
{
GetHintNode()->Unlock( GetHintDelay( GetHintNode()->HintType() ) );
SetHintNode( NULL );
}
#endif
}
}
@ -9358,6 +9376,13 @@ float CAI_BaseNPC::CalcIdealYaw( const Vector &vecTarget )
return UTIL_VecToYaw( vecProjection - GetLocalOrigin() );
}
#ifdef MAPBASE
// Allow hint nodes to override the yaw without needing to control AI
else if (GetHintNode() && GetHintNode()->OverridesNPCYaw( this ))
{
return GetHintNode()->Yaw();
}
#endif
else
{
return UTIL_VecToYaw ( vecTarget - GetLocalOrigin() );

View File

@ -980,11 +980,12 @@ bool CAI_BaseNPC::FindCoverFromEnemy( bool bNodesOnly, float flMinDistance, floa
// FIXME: add to goal
if (GetHintNode())
{
GetNavigator()->SetArrivalActivity( GetCoverActivity( GetHintNode() ) );
#ifdef MAPBASE
if (GetHintNode()->GetIgnoreFacing() != HIF_NO)
#endif
GetHintNode()->NPCHandleStartNav( this, true );
#else
GetNavigator()->SetArrivalActivity( GetCoverActivity( GetHintNode() ) );
GetNavigator()->SetArrivalDirection( GetHintNode()->GetDirection() );
#endif
}
return true;
@ -3431,6 +3432,17 @@ void CAI_BaseNPC::RunTask( const Task_t *pTask )
// If the yaw is locked, this function will not act correctly
Assert( GetMotor()->IsYawLocked() == false );
#ifdef MAPBASE
if ( GetHintNode() && GetHintNode()->OverridesNPCYaw( this ) )
{
// If the yaw is supposed to use that of a hint node, chain to TASK_FACE_HINTNODE
GetMotor()->SetIdealYaw( GetHintNode()->Yaw() );
GetMotor()->SetIdealYaw( CalcReasonableFacing( true ) ); // CalcReasonableFacing() is based on previously set ideal yaw
ChainRunTask( TASK_FACE_HINTNODE, pTask->flTaskData );
break;
}
#endif
Vector vecEnemyLKP = GetEnemyLKP();
if (!FInAimCone( vecEnemyLKP ))
{

View File

@ -14,6 +14,9 @@
#include "ai_basenpc.h"
#include "ai_localnavigator.h"
#include "ai_moveprobe.h"
#ifdef MAPBASE
#include "ai_hint.h"
#endif
#include "saverestore_utlvector.h"
// memdbgon must be the last include file in a .cpp file!!!
@ -836,9 +839,20 @@ void CAI_Motor::MoveFacing( const AILocalMoveGoal_t &move )
{
// FIXME: move this up to navigator so that path goals can ignore these overrides.
Vector dir;
#ifdef MAPBASE
if (IsDeceleratingToGoal() && (GetOuter()->GetHintNode() /*|| GetOuter()->m_hOpeningDoor*/))
{
// Don't let the facing queue interfere with arrival direction in important cases
dir = move.facing;
}
else
#endif
{
float flInfluence = GetFacingDirection( dir );
dir = move.facing * (1 - flInfluence) + dir * flInfluence;
VectorNormalize( dir );
}
// ideal facing direction
float idealYaw = UTIL_AngleMod( UTIL_VecToYaw( dir ) );

View File

@ -87,6 +87,9 @@ public:
const Vector & GetCurVel() const { return m_vecVelocity; }
virtual float OverrideMaxYawSpeed( Activity activity ) { return -1; }
#ifdef MAPBASE
virtual
#endif
bool IsDeceleratingToGoal() const { return false; }
//---------------------------------

View File

@ -999,13 +999,24 @@ int CAI_Navigator::GetArrivalSequence( int curSequence )
activity = ACT_IDLE;
}
sequence = GetOuter()->SelectWeightedSequence( GetOuter()->TranslateActivity( activity ), curSequence );
Activity translatedActivity = GetOuter()->TranslateActivity( activity );
sequence = GetOuter()->SelectWeightedSequence( translatedActivity, curSequence );
if ( sequence == ACT_INVALID )
{
#ifdef MAPBASE
if ( translatedActivity == ACT_SCRIPT_CUSTOM_MOVE )
{
// ACT_SCRIPT_CUSTOM_MOVE allows activity translation to resolve into specific sequences
sequence = GetOuter()->GetScriptCustomMoveSequence();
}
else
#endif
{
DevMsg( GetOuter(), "No appropriate sequence for arrival activity %s (%d)\n", GetOuter()->GetActivityName( GetPath()->GetArrivalActivity() ), GetPath()->GetArrivalActivity() );
sequence = GetOuter()->SelectWeightedSequence( GetOuter()->TranslateActivity( ACT_IDLE ), curSequence );
}
}
Assert( sequence != ACT_INVALID );
GetPath()->SetArrivalSequence( sequence );
}

View File

@ -411,7 +411,12 @@ int CAI_TacticalServices::FindCoverNode(const Vector &vNearPos, const Vector &vT
// --------------------------------------------------------
pNode->Lock( 1.0 );
#ifdef MAPBASE
if ( pNode->GetHint() && ( pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_MED || pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_LOW
|| pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_CUSTOM ) )
#else
if ( pNode->GetHint() && ( pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_MED || pNode->GetHint()->HintType() == HINT_TACTICAL_COVER_LOW ) )
#endif
{
if ( GetOuter()->GetHintNode() )
{