void CNPC_GMan::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_WAIT: // look at who I'm talking to if (m_flTalkTime > gpGlobals->curtime && m_hTalkTarget != NULL) { AddLookTarget( m_hTalkTarget->GetAbsOrigin(), 1.0, 2.0 ); } // look at player, but only if playing a "safe" idle animation else if (m_hPlayer != NULL && (GetSequence() == 0 || IsInC5A1()) ) { AddLookTarget( m_hPlayer->EyePosition(), 1.0, 3.0 ); } else { // Just center the head forward. Vector forward; GetVectors( &forward, NULL, NULL ); AddLookTarget( GetAbsOrigin() + forward * 12.0f, 1.0, 1.0 ); SetBoneController( 0, 0 ); } BaseClass::RunTask( pTask ); break; } SetBoneController( 0, 0 ); BaseClass::RunTask( pTask ); }
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 CHL1NPCTalker::IdleHeadTurn( CBaseEntity *pTarget, float flDuration, float flImportance ) { // Must be able to turn our head if (!(CapabilitiesGet() & bits_CAP_TURN_HEAD)) return; // If the target is invalid, or we're in a script, do nothing if ( ( !pTarget ) || ( m_NPCState == NPC_STATE_SCRIPT ) ) return; // Fill in a duration if we haven't specified one if ( flDuration == 0.0f ) { flDuration = random->RandomFloat( 2.0, 4.0 ); } // Add a look target AddLookTarget( pTarget, 1.0, flDuration ); }
void CFlextalkActor::ProcessSceneEvents( void ) { if ( HasSceneEvents() ) { BaseClass::ProcessSceneEvents( ); return; } // only do this if they have more than eyelid movement if (GetNumFlexControllers() > 2) { const char *pszExpression = flex_expression.GetString(); if (pszExpression && pszExpression[0] == '+' && pszExpression[1] != '\0') { int i; int j = atoi( &pszExpression[1] ); for (i = 0; i < GetNumFlexControllers(); i++) { m_flextarget[m_flexnum] = 0; } for (i = 0; i < 35 && predef_flexcontroller_names[i]; i++) { m_flexnum = LookupFlex( predef_flexcontroller_names[i] ); m_flextarget[m_flexnum] = predef_flexcontroller_values[j][i]; // Msg( "%s %.3f\n", predef_flexcontroller_names[i], predef_flexcontroller_values[j][i] ); } } else if (pszExpression && pszExpression[0] != '\0' && strcmp(pszExpression, "+") != 0) { char szExpression[128]; char szTemp[32]; Q_strncpy( szExpression, pszExpression ,sizeof(szExpression)); char *pszExpression = szExpression; while (*pszExpression != '\0') { if (*pszExpression == '+') *pszExpression = ' '; pszExpression++; } pszExpression = szExpression; while (*pszExpression) { if (*pszExpression != ' ') { if (*pszExpression == '-') { for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { m_flextarget[i] = 0; } } else if (*pszExpression == '?') { for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { Msg( "\"%s\" ", GetFlexControllerName( i ) ); } Msg( "\n" ); flex_expression.SetValue( "" ); } else { if (sscanf( pszExpression, "%31s", szTemp ) == 1) { m_flexnum = LookupFlex( szTemp ); if (m_flexnum != -1 && m_flextarget[m_flexnum] != 1) { m_flextarget[m_flexnum] = 1.0; // SetFlexTarget( m_flexnum ); } pszExpression += strlen( szTemp ) - 1; } } } pszExpression++; } } else if (m_flextime < gpGlobals->curtime) { m_flextime = gpGlobals->curtime + random->RandomFloat( 0.3, 0.5 ) * (30.0 / GetNumFlexControllers()); m_flexnum = (LocalFlexController_t)random->RandomInt( 0, GetNumFlexControllers() - 1 ); if (m_flextarget[m_flexnum] == 1) { m_flextarget[m_flexnum] = 0; } else if (stricmp( GetFlexControllerType( m_flexnum ), "phoneme" ) != 0) { if (strstr( GetFlexControllerName( m_flexnum ), "upper_raiser" ) == NULL) { Msg( "%s:%s\n", GetFlexControllerType( m_flexnum ), GetFlexControllerName( m_flexnum ) ); SetFlexTarget( m_flexnum, random->RandomFloat( 0.5, 1.0 ) ); } } } // slide it up. for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { float weight = GetFlexWeight( i ); if (weight != m_flextarget[i]) { weight = weight + (m_flextarget[i] - weight) / random->RandomFloat( 2.0, 4.0 ); } weight = clamp( weight, 0.0f, 1.0f ); SetFlexWeight( i, weight ); } if (flex_talk.GetInt() == -1) { m_istalking = 1; char pszSentence[256]; Q_snprintf( pszSentence,sizeof(pszSentence), "%s%d", STRING(m_iszSentence), m_sentence++ ); int sentenceIndex = engine->SentenceIndexFromName( pszSentence ); if (sentenceIndex >= 0) { Msg( "%d : %s\n", sentenceIndex, pszSentence ); CPASAttenuationFilter filter( this ); CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, SNDLVL_TALKING, 0, PITCH_NORM ); } else { m_sentence = 0; } flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -2) { m_flNextEyeLookTime = gpGlobals->curtime + 1000.0; } else if (flex_talk.GetInt() == -3) { m_flNextEyeLookTime = gpGlobals->curtime; flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -4) { AddLookTarget( UTIL_PlayerByIndex( 1 ), 0.5, flex_looktime.GetFloat() ); flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -5) { PickLookTarget( true ); flex_talk.SetValue( "0" ); } } }
void CNPC_Breen::Think( void ) { FaceAPIData headData = m_faceAPI->GetHeadData(); float now = engine->Time(); float adaptive = 1; if(headData.h_confidence > 0.0f) { // if too much time has elapsed since last tracking, we reset the head if(gpGlobals->curtime - m_lastTrackingTime > f_resetTimeout.GetFloat()) { for(int i = 0; i < m_poses.size(); i++) m_poses[i]->Reset(); for(int i = 0; i < m_poses.size(); i++) m_poses[i]->Reset(); } m_lastTrackingTime = gpGlobals->curtime; // cater for poor tracking by increasing the smoothing if the conf is low float conf = headData.h_confidence; m_avgConf.Smooth(conf, now); float normConf = (conf - CONF_SMOOTHING_MIN)/CONF_SMOOTHING_RANGE; adaptive += (1 - conf) * f_lowConfComp.GetFloat(); if(adaptive < m_adaptive_p) adaptive = max(1, m_adaptive_p - (now - m_lastThink)); m_adaptive_p = adaptive; } else { m_adaptive_p = 1.0f; // make Tim when not immitating people if(m_nextSmilePick < gpGlobals->curtime) { m_smileAmount = (rand()%100)/100.0f; m_nextSmilePick = gpGlobals->curtime + f_smilePickMin.GetInt() + rand()%f_smilePickFreq.GetInt(); } SetFlexWeight(m_smileFlex, m_smileAmount); } for(int i = 0; i < m_flexors.size(); i++) m_flexors[i]->Update(now, &headData, adaptive); // after flexors, before poses CAI_BaseActor::Think(); for(int i = 0; i < m_poses.size(); i++) m_poses[i]->Update(now, &headData, adaptive); if(headData.h_confidence > 0) { // make Breen look at the viewer Vector pos = GetAbsOrigin(); pos.x += f_gaze_offsetX.GetFloat(); pos.y += f_gaze_offsetY.GetFloat(); pos.z += f_gaze_offsetZ.GetFloat(); AddLookTarget(pos, 1.0, 1.0, 1.0); } m_lastThink = now; }