void G_GM_Unit::UpdateState() { if ((_ustate == g_us_move) && (_mesh->GetAnimationState(UNIT_CUST_ANIM_MOVE) == g_as_inactive)) MoveContinue(); if ((_ustate == g_us_test) && (_mesh->GetActiveAnimCount() == 0)) MoveStop(); }
void CAI_BlendedMotor::SetMoveScriptAnim( float flNewSpeed ) { // don't bother if the npc is dead if (!GetOuter()->IsAlive()) return; // insert ideal layers // FIXME: needs full transitions, as well as starting vs stopping sequences, leaning, etc. CAI_Navigator *pNavigator = GetNavigator(); SetPlaybackRate( m_flCurrRate ); // calc weight of idle animation layer that suppresses the run animation float flWeight = 0.0; if (GetIdealSpeed() > 0.0) { flWeight = 1.0 - (flNewSpeed / (GetIdealSpeed() * GetPlaybackRate())); } if (flWeight < 0.0) { m_flCurrRate = flNewSpeed / GetIdealSpeed(); m_flCurrRate = clamp( m_flCurrRate, 0.0, 1.0 ); SetPlaybackRate( m_flCurrRate ); flWeight = 0.0; } // Msg("weight %.3f rate %.3f\n", flWeight, m_flCurrRate ); m_flCurrRate = min( m_flCurrRate + (1.0 - m_flCurrRate) * 0.8, 1.0 ); if (m_nSavedGoalActivity == ACT_INVALID) { ResetGoalSequence(); } // detect state change Activity activity = GetOuter()->NPC_TranslateActivity( m_nSavedGoalActivity ); if ( activity != m_nSavedTranslatedGoalActivity ) { m_nSavedTranslatedGoalActivity = activity; m_nInteriorSequence = ACT_INVALID; m_nGoalSequence = pNavigator->GetArrivalSequence( m_nPrimarySequence ); } if (m_bDeceleratingToGoal) { // find that sequence to play when at goal m_nGoalSequence = pNavigator->GetArrivalSequence( m_nPrimarySequence ); if (m_nGoalSequence == ACT_INVALID) { m_nGoalSequence = GetInteriorSequence( m_nPrimarySequence ); } Assert( m_nGoalSequence != ACT_INVALID ); } if (m_flSecondaryWeight == 1.0 || (m_iSecondaryLayer != -1 && m_nPrimarySequence == m_nSecondarySequence)) { // secondary layer at full strength last time, delete the primary and shift down RemoveLayer( m_iPrimaryLayer, 0.0, 0.0 ); m_iPrimaryLayer = m_iSecondaryLayer; m_nPrimarySequence = m_nSecondarySequence; m_iSecondaryLayer = -1; m_nSecondarySequence = ACT_INVALID; m_flSecondaryWeight = 0.0; } // look for transition sequence if needed if (m_nSecondarySequence == ACT_INVALID) { if (!m_bDeceleratingToGoal && m_nGoalSequence != GetInteriorSequence( m_nPrimarySequence )) { // strob interior sequence in case it changed m_nGoalSequence = GetInteriorSequence( m_nPrimarySequence ); } if (m_nGoalSequence != ACT_INVALID && m_nPrimarySequence != m_nGoalSequence) { // Msg("From %s to %s\n", GetOuter()->GetSequenceName( m_nPrimarySequence ), GetOuter()->GetSequenceName( m_nGoalSequence ) ); m_nSecondarySequence = GetOuter()->FindTransitionSequence(m_nPrimarySequence, m_nGoalSequence, NULL); if (m_nSecondarySequence == ACT_INVALID) m_nSecondarySequence = m_nGoalSequence; } } // set blending for if (m_nSecondarySequence != ACT_INVALID) { if (m_iSecondaryLayer == -1) { m_iSecondaryLayer = AddLayeredSequence( m_nSecondarySequence, 0 ); SetLayerWeight( m_iSecondaryLayer, 0.0 ); if (m_nSecondarySequence == m_nGoalSequence) { SetLayerPlaybackRate( m_iSecondaryLayer, 0.0 ); } else { SetLayerPlaybackRate( m_iSecondaryLayer, 1.0 ); } SetLayerNoRestore( m_iSecondaryLayer, true ); m_flSecondaryWeight = 0.0; } m_flSecondaryWeight = min( m_flSecondaryWeight + 0.3, 1.0 ); if (m_flSecondaryWeight < 1.0) { SetLayerWeight( m_iPrimaryLayer, (flWeight - m_flSecondaryWeight * flWeight) / (1.0f - m_flSecondaryWeight * flWeight) ); SetLayerWeight( m_iSecondaryLayer, flWeight * m_flSecondaryWeight ); } else { SetLayerWeight( m_iPrimaryLayer, 0.0f ); SetLayerWeight( m_iSecondaryLayer, flWeight ); } } else { // recreate layer if missing if (m_iPrimaryLayer == -1) { MoveContinue(); } // try to catch a stale layer if (m_iSecondaryLayer != -1) { // secondary layer at full strength last time, delete the primary and shift down RemoveLayer( m_iSecondaryLayer, 0.0, 0.0 ); m_iSecondaryLayer = -1; m_nSecondarySequence = ACT_INVALID; m_flSecondaryWeight = 0.0; } // debounce // flWeight = flWeight * 0.5 + 0.5 * GetOuter()->GetLayerWeight( m_iPrimaryLayer ); SetLayerWeight( m_iPrimaryLayer, flWeight ); } }