void CAI_PlayerAlly::OnChangeRunningBehavior( CAI_BehaviorBase *pOldBehavior, CAI_BehaviorBase *pNewBehavior ) { BaseClass::OnChangeRunningBehavior( pOldBehavior, pNewBehavior ); CAI_FollowBehavior *pFollowBehavior; if ( dynamic_cast<CAI_FollowBehavior *>(pNewBehavior) != NULL ) { GetExpresser()->SetSpokeConcept( TLK_HELLO, NULL ); // Don't say hi after you've started following if ( IsOkToCombatSpeak() ) Speak( TLK_USE ); SetSpeechTarget( GetTarget() ); ClearCondition( COND_PLAYER_PUSHING ); } else if ( ( pFollowBehavior = dynamic_cast<CAI_FollowBehavior *>(pOldBehavior) ) != NULL ) { if ( !(m_afMemory & bits_MEMORY_PROVOKED) ) { if ( IsOkToCombatSpeak() ) { if ( pFollowBehavior->GetFollowTarget() == NULL ) Speak( TLK_UNUSE ); else Speak( TLK_STOP ); } SetSpeechTarget( FindNearestFriend(true) ); } } }
//========================================================= // IdleHello // Try to greet player first time he's seen //========================================================= int CAI_PlayerAlly::FIdleHello( void ) { if (!IsOkToSpeak()) return false; // if this is first time scientist has seen player, greet him if (!GetExpresser()->SpokeConcept(TLK_HELLO)) { // get a player CBaseEntity *pPlayer = FindNearestFriend(true); if (pPlayer) { if (FInViewCone(pPlayer) && FVisible(pPlayer)) { SetSpeechTarget( pPlayer ); Speak( TLK_HELLO ); return true; } } } return false; }
void CNPCSimpleTalker::OnStartingFollow( CBaseEntity *pTarget ) { GetExpresser()->SetSpokeConcept( TLK_HELLO, NULL ); // Don't say hi after you've started following if ( IsOkToSpeak() ) // don't speak if idle talk is blocked. player commanded/use follow will always speak Speak( TLK_STARTFOLLOW ); SetSpeechTarget( GetTarget() ); ClearCondition( COND_PLAYER_PUSHING ); }
//----------------------------------------------------------------------------- // Purpose: Tell this NPC to answer a question from another NPC //----------------------------------------------------------------------------- void CNPCSimpleTalker::SetAnswerQuestion( CNPCSimpleTalker *pSpeaker ) { if ( !m_hCine ) { SetCondition( COND_TALKER_RESPOND_TO_QUESTION ); } SetSpeechTarget( (CAI_BaseNPC *)pSpeaker ); }
void CHL1NPCTalker::StartFollowing( CBaseEntity *pLeader ) { if ( !HasSpawnFlags( SF_NPC_GAG ) ) { Speak( TLK_USE ); SetSpeechTarget( pLeader ); } BaseClass::StartFollowing( pLeader ); }
//========================================================= // FIdleStare //========================================================= int CAI_PlayerAlly::FIdleStare( void ) { if (!IsOkToSpeak()) return false; Speak( TLK_STARE ); SetSpeechTarget( FindNearestFriend( true ) ); return true; }
//----------------------------------------------------------------------------- // Purpose: Find a nearby friend to stare at //----------------------------------------------------------------------------- int CNPCSimpleTalker::FIdleStare( void ) { // Don't idly speak if our speech filter is preventing us if ( GetSpeechFilter() && GetSpeechFilter()->GetIdleModifier() == 0 ) return true; SpeakIfAllowed( TLK_STARE ); SetSpeechTarget( FindNearestFriend( true ) ); return true; }
int CAI_PlayerAlly::PlayScriptedSentence( const char *pszSentence, float delay, float volume, soundlevel_t soundlevel, bool bConcurrent, CBaseEntity *pListener ) { if ( !bConcurrent ) ShutUpFriends(); ClearCondition( COND_PLAYER_PUSHING ); // Forget about moving! I've got something to say! int sentenceIndex = BaseClass::PlayScriptedSentence( pszSentence, delay, volume, soundlevel, bConcurrent, pListener ); SetSpeechTarget( pListener ); return sentenceIndex; }
void CHL1NPCTalker::StopFollowing( void ) { if ( !(m_afMemory & bits_MEMORY_PROVOKED) ) { if ( !HasSpawnFlags( SF_NPC_GAG ) ) { Speak( TLK_UNUSE ); SetSpeechTarget( GetFollowTarget() ); } } BaseClass::StopFollowing(); }
void CNPCSimpleTalker::OnStoppingFollow( CBaseEntity *pTarget ) { if ( !(m_afMemory & bits_MEMORY_PROVOKED) ) { if ( IsOkToCombatSpeak() ) { if ( pTarget == NULL ) Speak( TLK_STOPFOLLOW ); else Speak( TLK_STOP ); } SetSpeechTarget( FindNearestFriend(true) ); } }
void CHL1NPCTalker::StartFollowing( CBaseEntity *pLeader ) { if ( !HasSpawnFlags( SF_NPC_GAG ) ) { if ( m_iszUse != NULL_STRING ) { PlaySentence( STRING( m_iszUse ), 0.0f ); } else { Speak( TLK_STARTFOLLOW ); } SetSpeechTarget( pLeader ); } BaseClass::StartFollowing( pLeader ); }
void CHL1NPCTalker::StopFollowing( void ) { if ( !(m_afMemory & bits_MEMORY_PROVOKED) ) { if ( !HasSpawnFlags( SF_NPC_GAG ) ) { if ( m_iszUnUse != NULL_STRING ) { PlaySentence( STRING( m_iszUnUse ), 0.0f ); } else { Speak( TLK_STOPFOLLOW ); } SetSpeechTarget( GetFollowTarget() ); } } BaseClass::StopFollowing(); }
void CHL1NPCTalker::FollowerUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { // Don't allow use during a scripted_sentence if ( GetUseTime() > gpGlobals->curtime ) return; if ( m_hCine && !m_hCine->CanInterrupt() ) return; if ( pCaller != NULL && pCaller->IsPlayer() ) { // Pre-disaster followers can't be used if ( m_spawnflags & SF_NPC_PREDISASTER ) { SetSpeechTarget( pCaller ); DeclineFollowing(); return; } } BaseClass::FollowerUse( pActivator, pCaller, useType, value ); }
//----------------------------------------------------------------------------- // Purpose: Say hello to the specified player //----------------------------------------------------------------------------- void CNPCSimpleTalker::SayHelloToPlayer( CBaseEntity *pPlayer ) { Assert( !GetExpresser()->SpokeConcept(TLK_HELLO) ); SetSpeechTarget( pPlayer ); Speak( TLK_HELLO ); DeferAllIdleSpeech( random->RandomFloat( 5, 10 ) ); CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); CAI_PlayerAlly *pTalker; for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ ) { pTalker = dynamic_cast<CAI_PlayerAlly *>(ppAIs[i]); if( pTalker && FVisible( pTalker ) ) { // Tell this guy he's already said hello to the player, too. pTalker->GetExpresser()->SetSpokeConcept( TLK_HELLO, NULL ); } } }
//========================================================= // FIdleSpeak // ask question of nearby friend, or make statement //========================================================= int CAI_PlayerAlly::FIdleSpeak ( void ) { // try to start a conversation, or make statement int pitch; if (m_NPCState == NPC_STATE_COMBAT ) { // Don't Idle Speak in combat. return false; } if (!IsOkToSpeak()) return false; Assert( GetExpresser()->SemaphoreIsAvailable() ); pitch = GetExpresser()->GetVoicePitch(); // player using this entity is alive and wounded? CBaseEntity *pTarget = GetTarget(); if ( pTarget != NULL ) { if ( pTarget->IsPlayer() ) { if ( pTarget->IsAlive() ) { SetSpeechTarget( GetTarget() ); if (GetExpresser()->CanSpeakConcept( TLK_PLHURT3) && (GetTarget()->m_iHealth <= GetTarget()->m_iMaxHealth / 8)) { //UTIL_EmitSoundDyn(edict(), CHAN_VOICE, m_szGrp[TLK_PLHURT3], 1.0, SNDLVL_TALKING, 0, pitch); Speak( TLK_PLHURT3 ); return true; } else if (GetExpresser()->CanSpeakConcept( TLK_PLHURT2) && (GetTarget()->m_iHealth <= GetTarget()->m_iMaxHealth / 4)) { //UTIL_EmitSoundDyn(edict(), CHAN_VOICE, m_szGrp[TLK_PLHURT2], 1.0, SNDLVL_TALKING, 0, pitch); Speak( TLK_PLHURT2 ); return true; } else if (GetExpresser()->CanSpeakConcept( TLK_PLHURT1) && (GetTarget()->m_iHealth <= GetTarget()->m_iMaxHealth / 2)) { //UTIL_EmitSoundDyn(edict(), CHAN_VOICE, m_szGrp[TLK_PLHURT1], 1.0, SNDLVL_TALKING, 0, pitch); Speak( TLK_PLHURT1 ); return true; } } else { //!!!KELLY - here's a cool spot to have the talkNPC talk about the dead player if we want. // "Oh dear, Gordon Freeman is dead!" -Scientist // "Damn, I can't do this without you." -Barney } } } // if there is a friend nearby to speak to, play sentence, set friend's response time, return CBaseEntity *pFriend = FindNearestFriend(false); if (pFriend && !(pFriend->IsMoving()) && (random->RandomInt(0,99) < 60)) { Speak( TLK_QUESTION ); // force friend to answer CAI_PlayerAlly *pTalkNPC = dynamic_cast<CNPCSimpleTalker *>(pFriend); if (pTalkNPC) { SetSpeechTarget( pFriend ); pTalkNPC->SetAnswerQuestion( this ); // UNDONE: This is EVIL!!! pTalkNPC->GetExpresser()->BlockSpeechUntil( GetExpresser()->GetTimeSpeechComplete() ); m_nSpeak++; return true; } } // otherwise, play an idle statement, try to face client when making a statement. if ( random->RandomInt(0,1) ) { //SENTENCEG_PlayRndSz( edict(), szIdleGroup, 1.0, SNDLVL_TALKING, 0, pitch ); CBaseEntity *pFriend = FindNearestFriend(true); if ( pFriend ) { SetSpeechTarget( pFriend ); Speak( TLK_IDLE ); m_nSpeak++; return true; } } // didn't speak GetExpresser()->BlockSpeechUntil( gpGlobals->curtime + 3 ); return false; }
// Prepare this talking NPC to answer question void CAI_PlayerAlly::SetAnswerQuestion( CAI_PlayerAlly *pSpeaker ) { if ( !m_hCine ) SetSchedule( SCHED_TALKER_IDLE_RESPONSE ); SetSpeechTarget( (CAI_BaseNPC *)pSpeaker ); }
void CNPCSimpleTalker::StartTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_TALKER_WAIT_FOR_SEMAPHORE: if ( GetExpresser()->SemaphoreIsAvailable( this ) ) TaskComplete(); break; case TASK_TALKER_SPEAK: // ask question or make statement FIdleSpeak(); TaskComplete(); break; case TASK_TALKER_RESPOND: // respond to question IdleRespond(); TaskComplete(); break; case TASK_TALKER_HELLO: // greet player FIdleHello(); TaskComplete(); break; case TASK_TALKER_STARE: // let the player know I know he's staring at me. FIdleStare(); TaskComplete(); break; case TASK_TALKER_LOOK_AT_CLIENT: case TASK_TALKER_CLIENT_STARE: // track head to the client for a while. SetWait( pTask->flTaskData ); break; case TASK_TALKER_EYECONTACT: break; case TASK_TALKER_IDEALYAW: if (GetSpeechTarget() != NULL) { GetMotor()->SetIdealYawToTarget( GetSpeechTarget()->GetAbsOrigin() ); } TaskComplete(); break; case TASK_TALKER_HEADRESET: // reset head position after looking at something SetSpeechTarget( NULL ); TaskComplete(); break; case TASK_TALKER_BETRAYED: Speak( TLK_BETRAYED ); TaskComplete(); break; case TASK_TALKER_STOPSHOOTING: // tell player to stop shooting Speak( TLK_NOSHOOT ); TaskComplete(); break; default: BaseClass::StartTask( pTask ); } }
void CAI_PlayerAlly::StartTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_TALKER_SPEAK: // ask question or make statement FIdleSpeak(); TaskComplete(); break; case TASK_TALKER_RESPOND: // respond to question IdleRespond(); TaskComplete(); break; case TASK_TALKER_HELLO: // greet player FIdleHello(); TaskComplete(); break; case TASK_TALKER_STARE: // let the player know I know he's staring at me. FIdleStare(); TaskComplete(); break; case TASK_TALKER_LOOK_AT_CLIENT: case TASK_TALKER_CLIENT_STARE: // track head to the client for a while. m_flWaitFinished = gpGlobals->curtime + pTask->flTaskData; break; case TASK_TALKER_EYECONTACT: break; case TASK_TALKER_IDEALYAW: if (GetSpeechTarget() != NULL) { GetMotor()->SetYawSpeed( 60 ); GetMotor()->SetIdealYawToTarget( GetSpeechTarget()->GetLocalOrigin() ); /* float yaw = VecToYaw(GetSpeechTarget()->GetLocalOrigin() - GetLocalOrigin()) - GetLocalAngles().y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; if (yaw < 0) { m_IdealYaw = min( yaw + 45, 0 ) + GetLocalAngles().y; } else { m_IdealYaw = max( yaw - 45, 0 ) + GetLocalAngles().y; } */ } TaskComplete(); break; case TASK_TALKER_HEADRESET: // reset head position after looking at something SetSpeechTarget( NULL ); TaskComplete(); break; case TASK_TALKER_BETRAYED: Speak( TLK_BETRAYED ); TaskComplete(); break; case TASK_TALKER_STOPSHOOTING: // tell player to stop shooting Speak( TLK_NOSHOOT ); TaskComplete(); break; case TASK_PLAY_SCRIPT: SetSpeechTarget( NULL ); BaseClass::StartTask( pTask ); break; case TASK_FIND_LOCK_HINTNODE_HEALTH: { m_flLastHealthKitSearch = gpGlobals->curtime + 5.0; if (!m_pHintNode) { m_pHintNode = CAI_Hint::FindHint( this, HINT_HEALTH_KIT, pTask->flTaskData, 1024 ); } if (m_pHintNode && m_pHintNode->Lock( this ) ) { TaskComplete(); } else { TaskFail(FAIL_NO_HINT_NODE); } } break; default: BaseClass::StartTask( pTask ); } }
//========================================================= // FIdleSpeak // ask question of nearby friend, or make statement //========================================================= int CNPCSimpleTalker::FIdleSpeak( void ) { // try to start a conversation, or make statement int pitch; if (!IsOkToSpeak()) return false; Assert( GetExpresser()->SemaphoreIsAvailable( this ) ); pitch = GetExpresser()->GetVoicePitch(); // player using this entity is alive and wounded? CBaseEntity *pTarget = GetTarget(); if ( pTarget != NULL ) { if ( pTarget->IsPlayer() ) { if ( pTarget->IsAlive() ) { SetSpeechTarget( GetTarget() ); if (GetExpresser()->CanSpeakConcept( TLK_PLHURT3) && (GetTarget()->m_iHealth <= GetTarget()->m_iMaxHealth / 8)) { Speak( TLK_PLHURT3 ); return true; } else if (GetExpresser()->CanSpeakConcept( TLK_PLHURT2) && (GetTarget()->m_iHealth <= GetTarget()->m_iMaxHealth / 4)) { Speak( TLK_PLHURT2 ); return true; } else if (GetExpresser()->CanSpeakConcept( TLK_PLHURT1) && (GetTarget()->m_iHealth <= GetTarget()->m_iMaxHealth / 2)) { Speak( TLK_PLHURT1 ); return true; } } else { //!!!KELLY - here's a cool spot to have the talkNPC talk about the dead player if we want. // "Oh dear, Gordon Freeman is dead!" -Scientist // "Damn, I can't do this without you." -Barney } } } // ROBIN: Disabled idle question & answer for now /* // if there is a friend nearby to speak to, play sentence, set friend's response time, return CBaseEntity *pFriend = FindNearestFriend(false); // 75% chance of talking to another citizen if one is available. if (pFriend && !(pFriend->IsMoving()) && random->RandomInt( 0, 3 ) != 0 ) { if ( SpeakQuestionFriend( pFriend ) ) { // force friend to answer CAI_PlayerAlly *pTalkNPC = dynamic_cast<CAI_PlayerAlly *>(pFriend); if (pTalkNPC && !pTalkNPC->HasSpawnFlags(SF_NPC_GAG) && !pTalkNPC->IsInAScript() ) { SetSpeechTarget( pFriend ); pTalkNPC->SetAnswerQuestion( this ); pTalkNPC->GetExpresser()->BlockSpeechUntil( GetExpresser()->GetTimeSpeechComplete() ); m_nSpeak++; } // Don't let anyone else butt in. DeferAllIdleSpeech( random->RandomFloat( TALKER_DEFER_IDLE_SPEAK_MIN, TALKER_DEFER_IDLE_SPEAK_MAX ), pTalkNPC ); return true; } } */ // Otherwise, play an idle statement, try to face client when making a statement. CBaseEntity *pFriend = FindNearestFriend(true); if ( pFriend ) { SetSpeechTarget( pFriend ); // If we're about to talk to the player, and we've never said hello, say hello first if ( !GetSpeechFilter() || !GetSpeechFilter()->NeverSayHello() ) { if ( GetExpresser()->CanSpeakConcept( TLK_HELLO ) && !GetExpresser()->SpokeConcept( TLK_HELLO ) ) { SayHelloToPlayer( pFriend ); return true; } } if ( Speak( TLK_IDLE ) ) { DeferAllIdleSpeech( random->RandomFloat( TALKER_DEFER_IDLE_SPEAK_MIN, TALKER_DEFER_IDLE_SPEAK_MAX ) ); m_nSpeak++; } else { // We failed to speak. Don't try again for a bit. m_flNextIdleSpeechTime = gpGlobals->curtime + 3; } return true; } // didn't speak m_flNextIdleSpeechTime = gpGlobals->curtime + 3; return false; }