void CAI_PlayerAlly::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_TALKER_CLIENT_STARE: case TASK_TALKER_LOOK_AT_CLIENT: if ( pTask->iTask == TASK_TALKER_CLIENT_STARE ) { // Get edict for one player CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( engine->PEntityOfEntIndex( 1 ) ); Assert( pPlayer ); // fail out if the player looks away or moves away. if ( ( pPlayer->GetLocalOrigin() - GetLocalOrigin() ).Length2D() > TLK_STARE_DIST ) { // player moved away. TaskFail("Player moved away"); } Vector forward; AngleVectors( pPlayer->GetLocalAngles(), &forward ); if ( UTIL_DotPoints( pPlayer->GetLocalOrigin(), GetLocalOrigin(), forward ) < m_flFieldOfView ) { // player looked away TaskFail("Player looked away"); } } if ( gpGlobals->curtime > m_flWaitFinished ) { TaskComplete(); } break; case TASK_TALKER_EYECONTACT: if (IsMoving() || !GetExpresser()->IsSpeaking() || GetSpeechTarget() == NULL) { TaskComplete(); } break; case TASK_WAIT_FOR_MOVEMENT: if (!GetExpresser()->IsSpeaking() || GetSpeechTarget() == NULL) { // override so that during walk, a scientist may talk and greet player FIdleHello(); if (random->RandomInt(0,m_nSpeak * 20) == 0) { FIdleSpeak(); } } BaseClass::RunTask( pTask ); break; default: BaseClass::RunTask( pTask ); } }
void CNPCSimpleTalker::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_TALKER_WAIT_FOR_SEMAPHORE: if ( GetExpresser()->SemaphoreIsAvailable( this ) ) TaskComplete(); break; case TASK_TALKER_CLIENT_STARE: case TASK_TALKER_LOOK_AT_CLIENT: if ( pTask->iTask == TASK_TALKER_CLIENT_STARE && AI_IsSinglePlayer() ) { // Get edict for one player CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); Assert( pPlayer ); // fail out if the player looks away or moves away. if ( ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2D() > TALKER_STARE_DIST ) { // player moved away. TaskFail("Player moved away"); } Vector forward; AngleVectors( pPlayer->GetLocalAngles(), &forward ); if ( UTIL_DotPoints( pPlayer->GetAbsOrigin(), GetAbsOrigin(), forward ) < m_flFieldOfView ) { // player looked away TaskFail("Player looked away"); } } if ( IsWaitFinished() ) { TaskComplete(); } break; case TASK_TALKER_EYECONTACT: if (IsMoving() || !GetExpresser()->IsSpeaking() || GetSpeechTarget() == NULL) { TaskComplete(); } break; case TASK_WAIT_FOR_MOVEMENT: FIdleSpeakWhileMoving(); BaseClass::RunTask( pTask ); break; default: BaseClass::RunTask( pTask ); } }
int CNPCSimpleTalker::SelectNonCombatSpeechSchedule() { if ( !IsOkToSpeak() ) return SCHED_NONE; // talk about world if ( ShouldSpeakRandom( m_nSpeak * 2, GetSpeechFilter() ? GetSpeechFilter()->GetIdleModifier() : 1.0 ) ) { //Msg("standing idle speak\n" ); return SCHED_TALKER_IDLE_SPEAK; } // failed to speak, so look at the player if he's around if ( AI_IsSinglePlayer() && GetExpresser()->CanSpeak() && HasCondition ( COND_SEE_PLAYER ) && random->RandomInt( 0, 6 ) == 0 ) { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); Assert( pPlayer ); if ( pPlayer ) { // watch the client. Vector forward; AngleVectors( pPlayer->GetLocalAngles(), &forward ); if ( ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2D() < TALKER_STARE_DIST && UTIL_DotPoints( pPlayer->GetAbsOrigin(), GetAbsOrigin(), forward ) >= m_flFieldOfView ) { // go into the special STARE schedule if the player is close, and looking at me too. return SCHED_TALKER_IDLE_WATCH_CLIENT_STARE; } return SCHED_TALKER_IDLE_WATCH_CLIENT; } } else { // look at who we're talking to if ( GetSpeechTarget() && GetExpresser()->IsSpeaking() ) return SCHED_TALKER_IDLE_EYE_CONTACT; } return SCHED_NONE; }
void CTalkMonster :: RunTask( const Task_t& task ) { switch( task.iTask ) { case TASK_TLK_CLIENT_STARE: case TASK_TLK_LOOK_AT_CLIENT: { edict_t *pPlayer; // track head to the client for a while. if( m_MonsterState == MONSTERSTATE_IDLE && !IsMoving() && !IsTalking() ) { // Get edict for one player pPlayer = g_engfuncs.pfnPEntityOfEntIndex( 1 ); if( pPlayer ) { IdleHeadTurn( pPlayer->v.origin ); } } else { // started moving or talking TaskFail(); return; } if( pPlayer ) { if( task.iTask == TASK_TLK_CLIENT_STARE ) { // fail out if the player looks away or moves away. if( ( pPlayer->v.origin - GetAbsOrigin() ).Length2D() > TLK_STARE_DIST ) { // player moved away. TaskFail(); } UTIL_MakeVectors( pPlayer->v.angles ); if( UTIL_DotPoints( pPlayer->v.origin, GetAbsOrigin(), gpGlobals->v_forward ) < m_flFieldOfView ) { // player looked away TaskFail(); } } } else { TaskFail(); } if( gpGlobals->time > m_flWaitFinished ) { TaskComplete(); } break; } case TASK_FACE_PLAYER: { // Get edict for one player edict_t *pPlayer = g_engfuncs.pfnPEntityOfEntIndex( 1 ); if( pPlayer ) { MakeIdealYaw( pPlayer->v.origin ); ChangeYaw( GetYawSpeed() ); IdleHeadTurn( pPlayer->v.origin ); if( gpGlobals->time > m_flWaitFinished && FlYawDiff() < 10 ) { TaskComplete(); } } else { TaskFail(); } break; } case TASK_TLK_EYECONTACT: { if( !IsMoving() && IsTalking() && m_hTalkTarget != NULL ) { // ALERT( at_console, "waiting %f\n", m_flStopTalkTime - gpGlobals->time ); IdleHeadTurn( m_hTalkTarget->GetAbsOrigin() ); } else { TaskComplete(); } break; } case TASK_WALK_PATH_FOR_UNITS: { float distance; distance = (m_vecLastPosition - GetAbsOrigin()).Length2D(); // Walk path until far enough away if ( distance > task.flData || MovementIsComplete() ) { TaskComplete(); RouteClear(); // Stop moving } break; } case TASK_WAIT_FOR_MOVEMENT: { if( IsTalking() && m_hTalkTarget != NULL ) { // ALERT(at_console, "walking, talking\n"); IdleHeadTurn( m_hTalkTarget->GetAbsOrigin() ); } else { IdleHeadTurn( GetAbsOrigin() ); // override so that during walk, a scientist may talk and greet player FIdleHello(); if( RANDOM_LONG( 0, m_nSpeak * 20 ) == 0 ) { FIdleSpeak(); } } CBaseMonster::RunTask( task ); if( TaskIsComplete() ) IdleHeadTurn( GetAbsOrigin() ); break; } default: { if( IsTalking() && m_hTalkTarget != NULL ) { IdleHeadTurn( m_hTalkTarget->GetAbsOrigin() ); } else { SetBoneController( 0, 0 ); } CBaseMonster::RunTask( task ); break; } } }
Schedule_t* CTalkMonster :: GetScheduleOfType ( int Type ) { switch( Type ) { case SCHED_MOVE_AWAY: return slMoveAway; case SCHED_MOVE_AWAY_FOLLOW: return slMoveAwayFollow; case SCHED_MOVE_AWAY_FAIL: return slMoveAwayFail; case SCHED_TARGET_FACE: // speak during 'use' if (RANDOM_LONG(0,99) < 2) //ALERT ( at_console, "target chase speak\n" ); return slIdleSpeakWait; else return slIdleStand; case SCHED_IDLE_STAND: { // if never seen player, try to greet him if (!FBitSet(m_bitsSaid, bit_saidHelloPlayer)) { return slIdleHello; } // sustained light wounds? if (!FBitSet(m_bitsSaid, bit_saidWoundLight) && ( GetHealth() <= ( GetMaxHealth() * 0.75))) { //SENTENCEG_PlayRndSz( this, m_szGrp[TLK_WOUND], 1.0, ATTN_IDLE, 0, GetVoicePitch() ); //CTalkMonster::g_talkWaitTime = gpGlobals->time + RANDOM_FLOAT(2.8, 3.2); PlaySentence( m_szGrp[TLK_WOUND], RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_IDLE ); SetBits(m_bitsSaid, bit_saidWoundLight); return slIdleStand; } // sustained heavy wounds? else if (!FBitSet(m_bitsSaid, bit_saidWoundHeavy) && ( GetHealth() <= ( GetMaxHealth() * 0.5))) { //SENTENCEG_PlayRndSz( this, m_szGrp[TLK_MORTAL], 1.0, ATTN_IDLE, 0, GetVoicePitch() ); //CTalkMonster::g_talkWaitTime = gpGlobals->time + RANDOM_FLOAT(2.8, 3.2); PlaySentence( m_szGrp[TLK_MORTAL], RANDOM_FLOAT(2.8, 3.2), VOL_NORM, ATTN_IDLE ); SetBits(m_bitsSaid, bit_saidWoundHeavy); return slIdleStand; } // talk about world if (FOkToSpeak() && RANDOM_LONG(0,m_nSpeak * 2) == 0) { //ALERT ( at_console, "standing idle speak\n" ); return slIdleSpeak; } if ( !IsTalking() && HasConditions ( bits_COND_SEE_CLIENT ) && RANDOM_LONG( 0, 6 ) == 0 ) { edict_t *pPlayer = g_engfuncs.pfnPEntityOfEntIndex( 1 ); if ( pPlayer ) { // watch the client. UTIL_MakeVectors ( pPlayer->v.angles ); if ( ( pPlayer->v.origin - GetAbsOrigin() ).Length2D() < TLK_STARE_DIST && UTIL_DotPoints( pPlayer->v.origin, GetAbsOrigin(), gpGlobals->v_forward ) >= m_flFieldOfView ) { // go into the special STARE schedule if the player is close, and looking at me too. return &slTlkIdleWatchClient[ 1 ]; } return slTlkIdleWatchClient; } } else { if (IsTalking()) // look at who we're talking to return slTlkIdleEyecontact; else // regular standing idle return slIdleStand; } // NOTE - caller must first CTalkMonster::GetScheduleOfType, // then check result and decide what to return ie: if sci gets back // slIdleStand, return slIdleSciStand } break; } return CBaseMonster::GetScheduleOfType( Type ); }
void CHL1NPCTalker::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_HL1TALKER_FOLLOW_WALK_PATH_FOR_UNITS: { float distance; distance = (m_vecLastPosition - GetLocalOrigin()).Length2D(); // Walk path until far enough away if ( distance > pTask->flTaskData || GetNavigator()->GetGoalType() == GOALTYPE_NONE ) { TaskComplete(); GetNavigator()->ClearGoal(); // Stop moving } break; } case TASK_TALKER_CLIENT_STARE: case TASK_TALKER_LOOK_AT_CLIENT: { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); // track head to the client for a while. if ( m_NPCState == NPC_STATE_IDLE && !IsMoving() && !GetExpresser()->IsSpeaking() ) { if ( pPlayer ) { IdleHeadTurn( pPlayer ); } } else { // started moving or talking TaskFail( "moved away" ); return; } if ( pTask->iTask == TASK_TALKER_CLIENT_STARE ) { // fail out if the player looks away or moves away. if ( ( pPlayer->GetAbsOrigin() - GetAbsOrigin() ).Length2D() > TALKER_STARE_DIST ) { // player moved away. TaskFail( NO_TASK_FAILURE ); } Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); if ( UTIL_DotPoints( pPlayer->GetAbsOrigin(), GetAbsOrigin(), vForward ) < m_flFieldOfView ) { // player looked away TaskFail( "looked away" ); } } if ( gpGlobals->curtime > m_flWaitFinished ) { TaskComplete( NO_TASK_FAILURE ); } break; } case TASK_WAIT_FOR_MOVEMENT: { if ( GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL) { // ALERT(at_console, "walking, talking\n"); IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime ); } else if ( GetEnemy() ) { IdleHeadTurn( GetEnemy() ); } BaseClass::RunTask( pTask ); break; } case TASK_FACE_PLAYER: { CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( pPlayer ) { //GetMotor()->SetIdealYaw( pPlayer->GetAbsOrigin() ); IdleHeadTurn( pPlayer ); if ( gpGlobals->curtime > m_flWaitFinished && GetMotor()->DeltaIdealYaw() < 10 ) { TaskComplete(); } } else { TaskFail( FAIL_NO_PLAYER ); } break; } case TASK_TALKER_EYECONTACT: { if (!IsMoving() && GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL) { // ALERT( at_console, "waiting %f\n", m_flStopTalkTime - gpGlobals->time ); IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime ); } BaseClass::RunTask( pTask ); break; } default: { if ( GetExpresser()->IsSpeaking() && GetSpeechTarget() != NULL) { IdleHeadTurn( GetSpeechTarget(), GetExpresser()->GetTimeSpeechComplete() - gpGlobals->curtime ); } else if ( GetEnemy() && m_NPCState == NPC_STATE_COMBAT ) { IdleHeadTurn( GetEnemy() ); } else if ( GetFollowTarget() ) { IdleHeadTurn( GetFollowTarget() ); } BaseClass::RunTask( pTask ); break; } } }
int CAI_PlayerAlly::TranslateSchedule( int scheduleType ) { switch( scheduleType ) { case SCHED_TARGET_FACE: // speak during 'use' if (random->RandomInt(0,99) < 2) //Msg("target chase speak\n" ); return SCHED_TALKER_IDLE_SPEAK_WAIT; // If we're hurt, look for a healthkit if ( m_flLastHealthKitSearch < gpGlobals->curtime && GetHealth() <= GetMaxHealth() / 2 ) return SCHED_TALKER_LOOK_FOR_HEALTHKIT; break; case SCHED_ALERT_STAND: // If we're hurt, look for a healthkit if ( m_flLastHealthKitSearch < gpGlobals->curtime && GetHealth() <= GetMaxHealth() / 2 ) return SCHED_TALKER_LOOK_FOR_HEALTHKIT; break; case SCHED_IDLE_STAND: { // if never seen player, try to greet him if (GetExpresser()->CanSpeakConcept( TLK_HELLO) && !GetExpresser()->SpokeConcept(TLK_HELLO)) { return SCHED_TALKER_IDLE_HELLO; } // If we're hurt, look for a healthkit if ( m_flLastHealthKitSearch < gpGlobals->curtime && GetHealth() <= GetMaxHealth() / 2 ) return SCHED_TALKER_LOOK_FOR_HEALTHKIT; // sustained light wounds? if (GetExpresser()->CanSpeakConcept( TLK_WOUND) && !GetExpresser()->SpokeConcept(TLK_WOUND) && (m_iHealth <= (m_iMaxHealth * 0.75))) { Speak( TLK_WOUND ); return SCHED_IDLE_STAND; } // sustained heavy wounds? else if (GetExpresser()->CanSpeakConcept( TLK_MORTAL) && (m_iHealth <= (m_iMaxHealth * 0.5))) { Speak( TLK_MORTAL ); return SCHED_IDLE_STAND; } // talk about world if (IsOkToSpeak() && random->RandomInt(0,m_nSpeak * 2) == 0) { //Msg("standing idle speak\n" ); return SCHED_TALKER_IDLE_SPEAK; } if ( !GetExpresser()->IsSpeaking() && HasCondition ( COND_SEE_PLAYER ) && random->RandomInt( 0, 6 ) == 0 ) { CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( engine->PEntityOfEntIndex( 1 ) ); Assert( pPlayer ); if ( pPlayer ) { // watch the client. Vector forward; AngleVectors( pPlayer->GetLocalAngles(), &forward ); if ( ( pPlayer->GetLocalOrigin() - GetLocalOrigin() ).Length2D() < TLK_STARE_DIST && UTIL_DotPoints( pPlayer->GetLocalOrigin(), GetLocalOrigin(), forward ) >= m_flFieldOfView ) { // go into the special STARE schedule if the player is close, and looking at me too. return SCHED_TALKER_IDLE_WATCH_CLIENT_STARE; } return SCHED_TALKER_IDLE_WATCH_CLIENT; } } else { if (GetExpresser()->IsSpeaking()) // look at who we're talking to return SCHED_TALKER_IDLE_EYE_CONTACT; else // regular standing idle return SCHED_IDLE_STAND; } } break; case SCHED_CHASE_ENEMY_FAILED: { int baseType = BaseClass::TranslateSchedule(scheduleType); if ( baseType != SCHED_CHASE_ENEMY_FAILED ) return baseType; return SCHED_TAKE_COVER_FROM_ENEMY; } break; } return BaseClass::TranslateSchedule( scheduleType ); }