bool CNPC_Infected::OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval ) { // required movement direction float flMoveYaw = UTIL_VecToYaw( move.dir ); // FIXME: move this up to navigator so that path goals can ignore these overrides. Vector dir; float flInfluence = GetFacingDirection( dir ); dir = move.facing * (1 - flInfluence) + dir * flInfluence; VectorNormalize( dir ); // ideal facing direction float idealYaw = UTIL_AngleMod( UTIL_VecToYaw( dir ) ); // FIXME: facing has important max velocity issues GetMotor()->SetIdealYawAndUpdate( idealYaw ); // find movement direction to compensate for not being turned far enough float flDiff = UTIL_AngleDiff( flMoveYaw, GetLocalAngles().y ); // Setup the 9-way blend parameters based on our speed and direction. Vector2D vCurMovePose( 0, 0 ); vCurMovePose.x = cos( DEG2RAD( flDiff ) ) * 1.0f; //flPlaybackRate; vCurMovePose.y = -sin( DEG2RAD( flDiff ) ) * 1.0f; //flPlaybackRate; SetPoseParameter( gm_nMoveXPoseParam, vCurMovePose.x ); SetPoseParameter( gm_nMoveYPoseParam, vCurMovePose.y ); // ==== Update Lean pose parameters if ( gm_nLeanYawPoseParam >= 0 ) { float targetLean = GetPoseParameter( gm_nMoveYPoseParam ) * 30.0f; float curLean = GetPoseParameter( gm_nLeanYawPoseParam ); if( curLean < targetLean ) curLean += MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*12.0f); //was 15.0f else curLean -= MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*12.0f); //was 15.0f SetPoseParameter( gm_nLeanYawPoseParam, curLean ); } if( gm_nLeanPitchPoseParam >= 0 ) { float targetLean = GetPoseParameter( gm_nMoveXPoseParam ) * -20.0f; //was -30.0f float curLean = GetPoseParameter( gm_nLeanPitchPoseParam ); if( curLean < targetLean ) curLean += MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*10.0f); //was 15.0f else curLean -= MIN(fabs(targetLean-curLean), GetAnimTimeInterval()*10.0f); //was 15.0f SetPoseParameter( gm_nLeanPitchPoseParam, curLean ); } return true; }
bool CFlex::IsSuppressedFlexAnimation( CSceneEventInfo *info ) { // check for suppression if the current info is a background if (info->m_pScene && info->m_pScene->IsBackground()) { // allow for slight jitter return m_flLastFlexAnimationTime > gpGlobals->curtime - GetAnimTimeInterval() * 1.5; } // keep track of last non-suppressable flex animation m_flLastFlexAnimationTime = gpGlobals->curtime; return false; }
void CHL1NPCTalker::IdleHeadTurn( const Vector &vTargetPos, float flDuration, float flImportance ) { if (!(CapabilitiesGet() & bits_CAP_TURN_HEAD)) return; if ( flDuration == 0.0f ) flDuration = random->RandomFloat( 2.0, 4.0 ); if ( vTargetPos == vec3_origin || m_NPCState == NPC_STATE_SCRIPT ) { SetHeadDirection( vTargetPos, GetAnimTimeInterval() ); } else { AddLookTarget( vTargetPos, 1.0, flDuration ); } }
void CBaseAnimatingOverlay::StudioFrameAdvance () { float flAdvance = GetAnimTimeInterval(); VerifyOrder(); BaseClass::StudioFrameAdvance(); for ( int i = 0; i < m_AnimOverlay.Count(); i++ ) { CAnimationLayer *pLayer = &m_AnimOverlay[i]; if (pLayer->IsActive()) { // Assert( !m_AnimOverlay[ i ].IsAbandoned() ); if (pLayer->IsKillMe()) { if (pLayer->m_flKillDelay > 0) { pLayer->m_flKillDelay -= flAdvance; pLayer->m_flKillDelay = clamp( pLayer->m_flKillDelay, 0.0, 1.0 ); } else if (pLayer->m_flWeight != 0.0f) { // give it at least one frame advance cycle to propagate 0.0 to client pLayer->m_flWeight -= pLayer->m_flKillRate * flAdvance; pLayer->m_flWeight = clamp( pLayer->m_flWeight.Get(), 0.0, 1.0 ); } else { // shift the other layers down in order if (ai_sequence_debug.GetBool() == true && m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) { Msg("removing %d (%d): %s : %5.3f (%.3f)\n", i, pLayer->m_nOrder.Get(), GetSequenceName( pLayer->m_nSequence ), pLayer->m_flCycle.Get(), pLayer->m_flWeight.Get() ); } FastRemoveLayer( i ); // needs at least one thing cycle dead to trigger sequence change pLayer->Dying(); continue; } } pLayer->StudioFrameAdvance( flAdvance, this ); if ( pLayer->m_bSequenceFinished && (pLayer->IsAutokill()) ) { pLayer->m_flWeight = 0.0f; pLayer->KillMe(); } } else if (pLayer->IsDying()) { pLayer->Dead(); } else if (pLayer->m_flWeight > 0.0) { // Now that the server blends, it is turning off layers all the time. Having a weight left over // when you're no longer marked as active is now harmless and commonplace. Just clean up. pLayer->Init( this ); pLayer->Dying(); } } if (ai_sequence_debug.GetBool() == true && m_debugOverlays & OVERLAY_NPC_SELECTED_BIT) { for ( int i = 0; i < m_AnimOverlay.Count(); i++ ) { if (m_AnimOverlay[ i ].IsActive()) { /* if (m_AnimOverlay[ i ].IsAbandoned()) { Msg(" %d abandoned %.2f (%.2f)\n", i, gpGlobals->curtime, m_AnimOverlay[ i ].m_flLastAccess ); } */ Msg(" %d (%d): %s : %5.3f (%.3f)\n", i, m_AnimOverlay[ i ].m_nOrder.Get(), GetSequenceName( m_AnimOverlay[ i ].m_nSequence ), m_AnimOverlay[ i ].m_flCycle.Get(), m_AnimOverlay[ i ].m_flWeight.Get() ); } } } VerifyOrder(); }
//----------------------------------------------------------------------------- // Purpose: execute any movement this sequence may have // Output : //----------------------------------------------------------------------------- bool CAI_BaseNPC::AutoMovement( CBaseEntity *pTarget, AIMoveTrace_t *pTraceResult ) { return AutoMovement( GetAnimTimeInterval(), pTarget, pTraceResult ); }