//----------------------------------------------------------------------------- // Purpose: // Input : *pTask - //----------------------------------------------------------------------------- void CAI_AssaultBehavior::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_WAIT_ASSAULT_DELAY: case TASK_AWAIT_ASSAULT_TIMEOUT: if ( m_hAssaultPoint ) { if ( m_hAssaultPoint->m_bInputForcedClear || (m_hAssaultPoint->m_bClearOnContact && HasCondition( COND_SEE_ENEMY )) ) { // If we're on an assault that should clear on contact, clear when we see an enemy TaskComplete(); } } if( GetOuter()->IsWaitFinished() && ( pTask->iTask == TASK_WAIT_ASSAULT_DELAY || !m_hAssaultPoint->m_bNeverTimeout ) ) { TaskComplete(); } break; case TASK_FACE_RALLY_POINT: case TASK_FACE_ASSAULT_POINT: GetMotor()->UpdateYaw(); if( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) { // Out early if the NPC can attack. TaskComplete(); } if ( GetOuter()->FacingIdeal() ) { TaskComplete(); } break; case TASK_AWAIT_CUE: // If we've lost our rally point, abort if ( !m_hRallyPoint ) { TaskFail("No rally point."); break; } if( PollAssaultCue() ) { TaskComplete(); } if ( IsForcingCrouch() ) break; if( GetOuter()->GetEnemy() && m_hRallyPoint->m_RallySequenceName == NULL_STRING ) { // I have an enemy and I'm NOT playing a custom animation. ChainRunTask( TASK_FACE_ENEMY, 0 ); } break; case TASK_WAIT_FOR_MOVEMENT: if ( ai_debug_assault.GetBool() ) { if ( IsCurSchedule( SCHED_MOVE_TO_ASSAULT_POINT ) ) { NDebugOverlay::Line( WorldSpaceCenter(), GetNavigator()->GetGoalPos(), 255,0,0, true,0.1); NDebugOverlay::Box( GetNavigator()->GetGoalPos(), -Vector(10,10,10), Vector(10,10,10), 255,0,0, 8, 0.1 ); } else if ( IsCurSchedule( SCHED_MOVE_TO_RALLY_POINT ) ) { NDebugOverlay::Line( WorldSpaceCenter(), GetNavigator()->GetGoalPos(), 0,255,0, true,0.1); NDebugOverlay::Box( GetNavigator()->GetGoalPos(), -Vector(10,10,10), Vector(10,10,10), 0,255,0, 8, 0.1 ); } } if ( m_hAssaultPoint && (m_hAssaultPoint->m_bInputForcedClear || (m_hAssaultPoint->m_bClearOnContact && HasCondition( COND_SEE_ENEMY ))) ) { DevMsg( "Assault Cleared due to Contact or Input!\n" ); ClearAssaultPoint(); TaskComplete(); return; } BaseClass::RunTask( pTask ); break; default: BaseClass::RunTask( pTask ); break; } }
void CAI_LeadBehavior::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_LEAD_SUCCEED: { if ( !IsSpeaking() ) { TaskComplete(); NotifyEvent( LBE_DONE ); } break; } case TASK_LEAD_ARRIVE: { if ( !IsSpeaking() ) { TaskComplete(); NotifyEvent( LBE_ARRIVAL_DONE ); } break; } case TASK_LEAD_MOVE_TO_RANGE: { // If we haven't spoken our start speech, move closer if ( !m_hasspokenstart) { ChainRunTask( TASK_MOVE_TO_GOAL_RANGE, m_leaddistance - 24 ); } else { ChainRunTask( TASK_MOVE_TO_GOAL_RANGE, m_retrievedistance ); if ( !TaskIsComplete() ) { // Transition to a walk when we get near the player // Check Z first, and only check 2d if we're within that Vector vecGoalPos = GetNavigator()->GetGoalPos(); float distance = fabs(vecGoalPos.z - GetLocalOrigin().z); bool bWithinZ = false; if ( distance < m_retrievedistance ) { distance = ( vecGoalPos - GetLocalOrigin() ).Length2D(); bWithinZ = true; } if ( distance > m_retrievedistance ) { Activity followActivity = ACT_WALK; if ( GetOuter()->GetState() == NPC_STATE_COMBAT || ( (!bWithinZ || distance < (m_retrievedistance*4)) && GetOuter()->GetState() != NPC_STATE_COMBAT ) ) { followActivity = ACT_RUN; } // Don't confuse move and shoot by resetting the activity every think Activity curActivity = GetNavigator()->GetMovementActivity(); switch( curActivity ) { case ACT_WALK_AIM: curActivity = ACT_WALK; break; case ACT_RUN_AIM: curActivity = ACT_RUN; break; } if ( curActivity != followActivity ) { GetNavigator()->SetMovementActivity(followActivity); } GetNavigator()->SetArrivalDirection( GetOuter()->GetTarget() ); } } } break; } case TASK_LEAD_RETRIEVE_WAIT: { ChainRunTask( TASK_WAIT_INDEFINITE ); break; } case TASK_LEAD_WALK_PATH: { // If we're leading, and we're supposed to run, run instead of walking if ( m_run && ( IsCurSchedule( SCHED_LEAD_WAITFORPLAYER, false ) || IsCurSchedule( SCHED_LEAD_PLAYER, false ) || IsCurSchedule( SCHED_LEAD_SPEAK_THEN_LEAD_PLAYER, false )|| IsCurSchedule( SCHED_LEAD_RETRIEVE, false ) ) ) { ChainRunTask( TASK_RUN_PATH ); } else { ChainRunTask( TASK_WALK_PATH ); } // While we're walking if ( TaskIsRunning() && IsCurSchedule( SCHED_LEAD_PLAYER, false ) ) { // If we're not speaking, and we haven't tried for a while, try to speak lead idle if ( m_flNextLeadIdle < gpGlobals->curtime && !IsSpeaking() ) { m_flNextLeadIdle = gpGlobals->curtime + RandomFloat( 10,15 ); if ( !m_args.iRetrievePlayer && HasCondition( COND_LEAD_FOLLOWER_LOST ) && HasCondition(COND_SEE_PLAYER) ) { Speak( TLK_LEAD_COMINGBACK ); } else { Speak( TLK_LEAD_IDLE ); } } } break; } default: BaseClass::RunTask( pTask); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CNPC_VehicleDriver::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_RANGE_ATTACK1: { // Vehicle driver has no animations, so fire a burst at the target CBaseEntity *pEnemy = GetEnemy(); if ( pEnemy ) { // TODO: Get a bodytarget from the firing point of the gun in the vehicle Vector vecTarget = GetEnemy()->BodyTarget( GetAbsOrigin(), false ); m_pVehicleInterface->NPC_AimPrimaryWeapon( vecTarget ); m_pVehicleInterface->NPC_PrimaryFire(); TaskComplete(); } else { TaskFail(FAIL_NO_ENEMY); return; } } break; case TASK_RANGE_ATTACK2: { // Vehicle driver has no animations, so fire a burst at the target CBaseEntity *pEnemy = GetEnemy(); if ( pEnemy ) { // TODO: Get a bodytarget from the firing point of the gun in the vehicle Vector vecTarget = GetEnemy()->BodyTarget( GetAbsOrigin(), false ); m_pVehicleInterface->NPC_AimSecondaryWeapon( vecTarget ); m_pVehicleInterface->NPC_SecondaryFire(); TaskComplete(); } else { TaskFail(FAIL_NO_ENEMY); return; } } break; case TASK_WAIT_FOR_MOVEMENT: { BaseClass::RunTask( pTask ); if ( HasCondition(COND_SEE_ENEMY) ) { // we can see the enemy if ( HasCondition(COND_CAN_RANGE_ATTACK2) ) { ChainRunTask( TASK_RANGE_ATTACK2, pTask->flTaskData ); } if ( HasCondition(COND_CAN_RANGE_ATTACK1) ) { ChainRunTask( TASK_RANGE_ATTACK1, pTask->flTaskData ); } } } break; default: BaseClass::RunTask( pTask ); break; } }