Beispiel #1
0
//=========================================================
// start task
//=========================================================
void CNPC_Stalker::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_STALKER_SCREAM:
	{
		if( gpGlobals->curtime > m_flNextScreamTime )
		{
			EmitSound( "NPC_Stalker.Scream" );
			m_flNextScreamTime = gpGlobals->curtime + random->RandomFloat( 10.0, 15.0 );
		}

		TaskComplete();
	}

	case TASK_ANNOUNCE_ATTACK:
	{
		// If enemy isn't facing me and I haven't attacked in a while
		// annouce my attack before I start wailing away
		CBaseCombatCharacter *pBCC = GetEnemyCombatCharacterPointer();

		if	(pBCC && (!pBCC->FInViewCone ( this )) &&
			 (gpGlobals->curtime - m_flLastAttackTime > 1.0) )
		{
				m_flLastAttackTime = gpGlobals->curtime;

				// Always play this sound
				EmitSound( "NPC_Stalker.Scream" );
				m_flNextScrambleSoundTime = gpGlobals->curtime + 2;
				m_flNextBreatheSoundTime = gpGlobals->curtime + 2;

				// Wait two seconds
				SetWait( 2.0 );
				SetActivity(ACT_IDLE);
		}
		break;
	}
	case TASK_STALKER_ZIGZAG:
			break;
	case TASK_RANGE_ATTACK1:
		{
			CBaseEntity *pEnemy = GetEnemy();
			if (pEnemy)
			{
				m_vLaserTargetPos = GetEnemyLKP() + pEnemy->GetViewOffset();

				// Never hit target on first try
				Vector missPos = m_vLaserTargetPos;
				
				if( pEnemy->Classify() == CLASS_BULLSEYE && hl2_episodic.GetBool() )
				{
					missPos.x += 60 + 120*random->RandomInt(-1,1);
					missPos.y += 60 + 120*random->RandomInt(-1,1);
				}
				else
				{
					missPos.x += 80*random->RandomInt(-1,1);
					missPos.y += 80*random->RandomInt(-1,1);
				}

				// ----------------------------------------------------------------------
				// If target is facing me and not running towards me shoot below his feet
				// so he can see the laser coming
				// ----------------------------------------------------------------------
				CBaseCombatCharacter *pBCC = ToBaseCombatCharacter(pEnemy);
				if (pBCC)
				{
					Vector targetToMe = (pBCC->GetAbsOrigin() - GetAbsOrigin());
					Vector vBCCFacing = pBCC->BodyDirection2D( );
					if ((DotProduct(vBCCFacing,targetToMe) < 0) &&
						(pBCC->GetSmoothedVelocity().Length() < 50))
					{
						missPos.z -= 150;
					}
					// --------------------------------------------------------
					// If facing away or running towards laser,
					// shoot above target's head 
					// --------------------------------------------------------
					else
					{
						missPos.z += 60;
					}
				}
				m_vLaserDir = missPos - LaserStartPosition(GetAbsOrigin());
				VectorNormalize(m_vLaserDir);	
			}
			else
			{
				TaskFail(FAIL_NO_ENEMY);
				return;
			}

			StartAttackBeam();
			SetActivity(ACT_RANGE_ATTACK1);
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_LOS:
		{
			if ( GetEnemy() != NULL )
			{
				BaseClass:: StartTask( pTask );
				return;
			}

			Vector posLos;

			if (GetTacticalServices()->FindLos(m_vLaserCurPos, m_vLaserCurPos, MIN_STALKER_FIRE_RANGE, MAX_STALKER_FIRE_RANGE, 1.0, &posLos))
			{
				AI_NavGoal_t goal( posLos, ACT_RUN, AIN_HULL_TOLERANCE );
				GetNavigator()->SetGoal( goal );
			}
			else
			{
				TaskFail(FAIL_NO_SHOOT);
			}
			break;
		}
	case TASK_FACE_ENEMY:
		{
			if ( GetEnemy() != NULL )
			{
				BaseClass:: StartTask( pTask );
				return;
			}
			GetMotor()->SetIdealYawToTarget( m_vLaserCurPos );
			break;
		}
	default: 
		BaseClass:: StartTask( pTask );
		break;
	}
}
Beispiel #2
0
//=========================================================
// start task
//=========================================================
void CNPC_Houndeye::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_HOUND_GET_PATH_TO_CIRCLE:
	{
		if (GetEnemy() == NULL)
		{
			TaskFail(FAIL_NO_ENEMY);
		}
		else 
		{
			Vector vTargetPos = GetEnemyLKP();
			vTargetPos.z	= GetFloorZ(vTargetPos);

			if (GetNavigator()->SetRadialGoal(vTargetPos, random->RandomInt(50,500), 90, 175, m_bLoopClockwise))
			{
				TaskComplete();
				return;
			}
			TaskFail(FAIL_NO_ROUTE);
		}
		break;
	}
	case TASK_HOUND_REVERSE_STRAFE_DIR:
	{
		// Try the other direction
		m_bLoopClockwise = (m_bLoopClockwise) ? false : true;
		TaskComplete();
		break;
	}

	// Override to set appropriate distances
	case TASK_GET_PATH_TO_ENEMY_LOS:
	{
		float			flMaxRange	= HOUNDEYE_MAX_ATTACK_RADIUS * 0.9;
		float			flMinRange	= HOUNDEYE_MIN_ATTACK_RADIUS;
		Vector 			posLos;
		bool			foundLos	= false;
		
		if (GetEnemy() != NULL)
		{
			foundLos = GetTacticalServices()->FindLos(GetEnemyLKP(),GetEnemy()->EyePosition(), flMinRange, flMaxRange, 0.0, &posLos);
		}
		else
		{
			TaskFail(FAIL_NO_TARGET);
			return;
		}

		if (foundLos)
		{
			GetNavigator()->SetGoal( AI_NavGoal_t( posLos, ACT_RUN, AIN_HULL_TOLERANCE ) );
		}
		else
		{
			TaskFail(FAIL_NO_SHOOT);
		}
		break;
	}

	case TASK_HOUND_FALL_ASLEEP:
		{
			m_fAsleep = true; // signal that hound is lying down (must stand again before doing anything else!)
			TaskComplete( true );
			break;
		}
	case TASK_HOUND_WAKE_UP:
		{
			m_fAsleep = false; // signal that hound is standing again
			TaskComplete( true );
			break;
		}
	case TASK_HOUND_OPEN_EYE:
		{
			m_fDontBlink = false; // turn blinking back on and that code will automatically open the eye
			TaskComplete( true );
			break;
		}
	case TASK_HOUND_CLOSE_EYE:
		{
//<<TEMP>>			pev->skin = 0;
			m_fDontBlink = true; // tell blink code to leave the eye alone.
			break;
		}
	case TASK_HOUND_THREAT_DISPLAY:
		{
			SetIdealActivity( ACT_IDLE_ANGRY );
			break;
		}
	case TASK_HOUND_HOP_BACK:
		{
			SetIdealActivity( ACT_LEAP );
			break;
		}
	case TASK_RANGE_ATTACK1:
		{
			SetIdealActivity( ACT_RANGE_ATTACK1 );
			break;
		}
	default: 
		{
			BaseClass::StartTask(pTask);
			break;
		}
	}
}
void CAI_StandoffBehavior::StartTask( const Task_t *pTask )
{
	bool fCallBase = false;
	
	switch ( pTask->iTask )
	{
		case TASK_RANGE_ATTACK1:
		{
			m_ShotRegulator.OnFiredWeapon();
			fCallBase = true;
			break;
		}
		
		case TASK_FIND_COVER_FROM_ENEMY:
		{
			StandoffMsg( "TASK_FIND_COVER_FROM_ENEMY\n" );

			// If within time window to force change
			if ( !m_params.fStayAtCover && (!m_TimeForceCoverHint.Expired() || m_RandomCoverChangeTimer.Expired()) )
			{
				m_TimeForceCoverHint.Force();
				m_RandomCoverChangeTimer.Set( 8, 16, false );

				// @TODO (toml 03-24-03):  clean this up be tool-izing base tasks. Right now, this is here to force to not use lateral cover search
				CBaseEntity *pEntity = GetEnemy();

				if ( pEntity == NULL )
				{
					// Find cover from self if no enemy available
					pEntity = GetOuter();
				}

				CBaseEntity *pLeader = GetPlayerLeader();
				if ( pLeader )
				{
					m_PlayerMoveMonitor.SetMark( pLeader, 60 );
				}

				Vector					coverPos			= vec3_origin;
				CAI_TacticalServices *	pTacticalServices	= GetTacticalServices();
				const Vector &			enemyPos			= pEntity->GetAbsOrigin();
				Vector					enemyEyePos			= pEntity->EyePosition();
				float					coverRadius			= GetOuter()->CoverRadius();
				const Vector &			goalPos				= GetStandoffGoalPosition();
				bool					bTryGoalPosFirst	= true;

				if( pLeader && m_vecStandoffGoalPosition == GOAL_POSITION_INVALID )
				{
					if( random->RandomInt(1, 100) <= 50 )
					{
						// Half the time, if the player is leading, try to find a spot near them
						bTryGoalPosFirst = false;
						StandoffMsg( "Not trying goal pos\n" );
					}
				}

				if( bTryGoalPosFirst )
				{
					// Firstly, try to find cover near the goal position.
					pTacticalServices->FindCoverPos( goalPos, enemyPos, enemyEyePos, 0, 15*12, &coverPos );

					if ( coverPos == vec3_origin )
						pTacticalServices->FindCoverPos( goalPos, enemyPos, enemyEyePos, 15*12-0.1, 40*12, &coverPos );

					StandoffMsg1( "Trying goal pos, %s\n", ( coverPos == vec3_origin  ) ? "failed" :  "succeeded" );
				}

				if ( coverPos == vec3_origin  ) 
				{
					// Otherwise, find a node near to self
					StandoffMsg( "Looking for near cover\n" );
					if ( !GetTacticalServices()->FindCoverPos( enemyPos, enemyEyePos, 0, coverRadius, &coverPos ) ) 
					{
						// Try local lateral cover
						if ( !GetTacticalServices()->FindLateralCover( enemyEyePos, &coverPos ) )
						{
							// At this point, try again ignoring front lines. Any cover probably better than hanging out in the open
							m_fIgnoreFronts = true;
							if ( !GetTacticalServices()->FindCoverPos( enemyPos, enemyEyePos, 0, coverRadius, &coverPos ) ) 
							{
								if ( !GetTacticalServices()->FindLateralCover( enemyEyePos, &coverPos ) )
								{
									Assert( coverPos == vec3_origin );
								}
							}
							m_fIgnoreFronts = false;
						}
					}
				}

				if ( coverPos != vec3_origin )
				{
					AI_NavGoal_t goal(GOALTYPE_COVER, coverPos, ACT_RUN, AIN_HULL_TOLERANCE, AIN_DEF_FLAGS);
					GetNavigator()->SetGoal( goal );

					GetOuter()->m_flMoveWaitFinished = gpGlobals->curtime + pTask->flTaskData;
					TaskComplete();
				}
				else
					TaskFail(FAIL_NO_COVER);
			}
			else
			{
				fCallBase = true;
			}
			break;
		}

		default:
		{
			fCallBase = true;
		}
	}
	
	if ( fCallBase )
		BaseClass::StartTask( pTask );
}