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 );
}
Example #4
0
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;
}