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 );
	}
}
Exemple #2
0
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 );
	}
}
Exemple #3
0
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;
}
Exemple #4
0
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;
		}
	}
}
Exemple #5
0
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 );
}