//----------------------------------------------------------------------------- // TASK_RANGE_ATTACK1 //----------------------------------------------------------------------------- void CAI_BaseHumanoid::StartTaskRangeAttack1( const Task_t *pTask ) { if ( ( CapabilitiesGet() & bits_CAP_USE_SHOT_REGULATOR ) == 0 ) { BaseClass::StartTask( pTask ); return; } // Can't shoot if we're in the rest interval; fail the schedule if ( GetShotRegulator()->IsInRestInterval() ) { TaskFail( "Shot regulator in rest interval" ); return; } if ( GetShotRegulator()->ShouldShoot() ) { OnRangeAttack1(); ResetIdealActivity( ACT_RANGE_ATTACK1 ); } else { // This can happen if we start while in the middle of a burst // which shouldn't happen, but given the chaotic nature of our AI system, // does occasionally happen. ResetIdealActivity( ACT_IDLE_ANGRY ); } }
void CNPC_Monk::StartTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_RELOAD: { if ( GetActiveWeapon() && GetActiveWeapon()->HasPrimaryAmmo() ) { // Don't reload if you have done so while moving (See BACK_AWAY_AND_RELOAD schedule). TaskComplete(); return; } if( m_iNumZombies >= 2 && random->RandomInt( 1, 3 ) == 1 ) { SpeakIfAllowed( TLK_ATTACKING ); } Activity reloadGesture = TranslateActivity( ACT_GESTURE_RELOAD ); if ( reloadGesture != ACT_INVALID && IsPlayingGesture( reloadGesture ) ) { ResetIdealActivity( ACT_IDLE ); return; } BaseClass::StartTask( pTask ); } break; default: BaseClass::StartTask( pTask ); break; } }
void CZombie::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_ZOMBIE_ATTACK_DOOR: { if ( IsActivityFinished() ) { if ( m_DurationDoorBash.Expired() ) { TaskComplete(); m_NextTimeToStartDoorBash.Reset(); } else ResetIdealActivity( SelectDoorBash() ); } break; } case TASK_ZOMBIE_CHARGE_ENEMY: { break; } case TASK_ZOMBIE_EXPRESS_ANGER: { if ( IsActivityFinished() ) TaskComplete(); break; } default: BaseClass::RunTask( pTask ); break; } }
void CASW_Harvester::StartTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_LAY_CRITTER: { ResetIdealActivity((Activity) ACT_HARVESTER_LAY_CRITTER); break; } default: BaseClass::StartTask( pTask ); break; } }
//----------------------------------------------------------------------------- // TASK_RANGE_ATTACK1 / TASK_RANGE_ATTACK2 / etc. //----------------------------------------------------------------------------- void CAI_BaseHumanoid::RunTaskRangeAttack1( const Task_t *pTask ) { if ( ( CapabilitiesGet() & bits_CAP_USE_SHOT_REGULATOR ) == 0 ) { BaseClass::RunTask( pTask ); return; } AutoMovement( ); Vector vecEnemyLKP = GetEnemyLKP(); // If our enemy was killed, but I'm not done animating, the last known position comes // back as the origin and makes the me face the world origin if my attack schedule // doesn't break when my enemy dies. (sjb) if( vecEnemyLKP != vec3_origin ) { if ( ( pTask->iTask == TASK_RANGE_ATTACK1 || pTask->iTask == TASK_RELOAD ) && ( CapabilitiesGet() & bits_CAP_AIM_GUN ) && FInAimCone( vecEnemyLKP ) ) { // Arms will aim, so leave body yaw as is GetMotor()->SetIdealYawAndUpdate( GetMotor()->GetIdealYaw(), AI_KEEP_YAW_SPEED ); } else { GetMotor()->SetIdealYawToTargetAndUpdate( vecEnemyLKP, AI_KEEP_YAW_SPEED ); } } if ( IsActivityFinished() ) { if ( !GetEnemy() || !GetEnemy()->IsAlive() ) { TaskComplete(); return; } if ( !GetShotRegulator()->IsInRestInterval() ) { if ( GetShotRegulator()->ShouldShoot() ) { OnRangeAttack1(); ResetIdealActivity( ACT_RANGE_ATTACK1 ); } return; } TaskComplete(); } }
//--------------------------------------------------------- // Purpose: //--------------------------------------------------------- void CNPC_Assassin::StartTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_ASSASSIN_SET_EYE_STATE: { SetEyeState( (eyeState_t) ( (int) pTask->flTaskData ) ); TaskComplete(); } break; case TASK_ASSASSIN_EVADE: { Activity flipAct = ACT_INVALID; const Vector *avoidPos = ( GetEnemy() != NULL ) ? &(GetEnemy()->GetAbsOrigin()) : NULL; for ( int i = FLIP_LEFT; i < NUM_FLIP_TYPES; i++ ) { if ( CanFlip( i, flipAct, avoidPos ) ) { // Don't flip back to where we just were if ( ( ( i == FLIP_LEFT ) && ( m_nLastFlipType == FLIP_RIGHT ) ) || ( ( i == FLIP_RIGHT ) && ( m_nLastFlipType == FLIP_LEFT ) ) || ( ( i == FLIP_FORWARD ) && ( m_nLastFlipType == FLIP_BACKWARD ) ) || ( ( i == FLIP_BACKWARD ) && ( m_nLastFlipType == FLIP_FORWARD ) ) ) { flipAct = ACT_INVALID; continue; } m_nNumFlips--; ResetIdealActivity( flipAct ); m_flNextFlipTime = gpGlobals->curtime + 2.0f; m_nLastFlipType = i; break; } } if ( flipAct == ACT_INVALID ) { m_nNumFlips = 0; m_nLastFlipType = -1; m_flNextFlipTime = gpGlobals->curtime + 2.0f; TaskFail( "Unable to find flip evasion direction!\n" ); } } break; case TASK_ASSASSIN_GET_PATH_TO_VANTAGE_POINT: { assert( GetEnemy() != NULL ); if ( GetEnemy() == NULL ) break; Vector goalPos; CHintCriteria hint; // Find a disadvantage node near the player, but away from ourselves hint.SetHintType( HINT_TACTICAL_ENEMY_DISADVANTAGED ); hint.AddExcludePosition( GetAbsOrigin(), 256 ); hint.AddExcludePosition( GetEnemy()->GetAbsOrigin(), 256 ); if ( ( m_pSquad != NULL ) && ( m_pSquad->NumMembers() > 1 ) ) { AISquadIter_t iter; for ( CAI_BaseNPC *pSquadMember = m_pSquad->GetFirstMember( &iter ); pSquadMember; pSquadMember = m_pSquad->GetNextMember( &iter ) ) { if ( pSquadMember == NULL ) continue; hint.AddExcludePosition( pSquadMember->GetAbsOrigin(), 128 ); } } hint.SetFlag( bits_HINT_NODE_NEAREST ); CAI_Hint *pHint = CAI_HintManager::FindHint( this, GetEnemy()->GetAbsOrigin(), &hint ); if ( pHint == NULL ) { TaskFail( "Unable to find vantage point!\n" ); break; } pHint->GetPosition( this, &goalPos ); AI_NavGoal_t goal( goalPos ); //Try to run directly there if ( GetNavigator()->SetGoal( goal ) == false ) { TaskFail( "Unable to find path to vantage point!\n" ); break; } TaskComplete(); } break; default: BaseClass::StartTask( pTask ); break; } }
void CNPC_AlienGrunt::StartTask ( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_AGRUNT_RANGE_ATTACK1_NOTURN: { SetLastAttackTime( gpGlobals->curtime ); ResetIdealActivity( ACT_RANGE_ATTACK1 ); } break; case TASK_AGRUNT_GET_PATH_TO_ENEMY_CORPSE: { Vector forward; AngleVectors( GetAbsAngles(), &forward ); Vector flEnemyLKP = GetEnemyLKP(); GetNavigator()->SetGoal( flEnemyLKP - forward * 64, AIN_CLEAR_TARGET); if ( GetNavigator()->SetGoal( flEnemyLKP - forward * 64, AIN_CLEAR_TARGET) ) { TaskComplete(); } else { Msg ( "AGruntGetPathToEnemyCorpse failed!!\n" ); TaskFail( FAIL_NO_ROUTE ); } } break; case TASK_AGRUNT_SETUP_HIDE_ATTACK: // alien grunt shoots hornets back out into the open from a concealed location. // try to find a spot to throw that gives the smart weapon a good chance of finding the enemy. // ideally, this spot is along a line that is perpendicular to a line drawn from the agrunt to the enemy. CHL1BaseNPC *pEnemyMonsterPtr; pEnemyMonsterPtr = (CHL1BaseNPC *)GetEnemy()->MyNPCPointer(); if ( pEnemyMonsterPtr ) { Vector vecCenter, vForward, vRight, vecEnemyLKP; QAngle angTmp; trace_t tr; BOOL fSkip; fSkip = FALSE; vecCenter = WorldSpaceCenter(); vecEnemyLKP = GetEnemyLKP(); VectorAngles( vecEnemyLKP - GetAbsOrigin(), angTmp ); SetAbsAngles( angTmp ); AngleVectors( GetAbsAngles(), &vForward, &vRight, NULL ); UTIL_TraceLine( WorldSpaceCenter() + vForward * 128, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); if ( tr.fraction == 1.0 ) { GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() + vRight * 128 ); fSkip = TRUE; TaskComplete(); } if ( !fSkip ) { UTIL_TraceLine( WorldSpaceCenter() - vForward * 128, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); if ( tr.fraction == 1.0 ) { GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() - vRight * 128 ); fSkip = TRUE; TaskComplete(); } } if ( !fSkip ) { UTIL_TraceLine( WorldSpaceCenter() + vForward * 256, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); if ( tr.fraction == 1.0 ) { GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() + vRight * 256 ); fSkip = TRUE; TaskComplete(); } } if ( !fSkip ) { UTIL_TraceLine( WorldSpaceCenter() - vForward * 256, vecEnemyLKP, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); if ( tr.fraction == 1.0 ) { GetMotor()->SetIdealYawToTargetAndUpdate ( GetAbsOrigin() - vRight * 256 ); fSkip = TRUE; TaskComplete(); } } if ( !fSkip ) { TaskFail( FAIL_NO_COVER ); } } else { Msg ( "AGRunt - no enemy monster ptr!!!\n" ); TaskFail( FAIL_NO_ENEMY ); } break; default: BaseClass::StartTask ( pTask ); break; } }