//=========================================================
// Start task - selects the correct activity and performs
// any necessary calculations to start the next task on the
// schedule.  OVERRIDDEN for bullsquid because it needs to
// know explicitly when the last attempt to chase the enemy
// failed, since that impacts its attack choices.
//=========================================================
void CNPC_Bullsquid::StartTask ( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_MELEE_ATTACK2:
		{
			if (GetEnemy())
			{
				GrowlSound();

				m_flLastAttackTime = gpGlobals->curtime;

				BaseClass::StartTask ( pTask );
			}
			break;
		}
	case TASK_SQUID_HOPTURN:
		{
			SetActivity ( ACT_HOP );
			
			if ( GetEnemy() )
			{
				Vector	vecFacing = ( GetEnemy()->GetAbsOrigin() - GetAbsOrigin() );
				VectorNormalize( vecFacing );

				GetMotor()->SetIdealYaw( vecFacing );
			}

			break;
		}
	case TASK_SQUID_EAT:
		{
			m_flHungryTime = gpGlobals->curtime + pTask->flTaskData;
			TaskComplete();
			break;
		}
	default:
		{
			BaseClass::StartTask ( pTask );
			break;
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAI_PassengerBehaviorZombie::StartDismount( void )
{
	// Leap off the vehicle
	int nSequence = FindExitSequence();
	Assert( nSequence != -1 );

	SetTransitionSequence( nSequence );
	GetOuter()->SetIdealActivity( ACT_SCRIPT_CUSTOM_MOVE );

	// This removes the NPC from the vehicle's handling and fires all necessary outputs
	m_hVehicle->RemovePhysicsChild( GetOuter() );
	m_hVehicle->NPC_RemovePassenger( GetOuter() );
	m_hVehicle->NPC_FinishedExitVehicle( GetOuter(), (IsPassengerHostile()==false) );

	// Detach from the parent
	GetOuter()->SetParent( NULL );
	GetOuter()->SetMoveType( MOVETYPE_STEP );
	GetMotor()->SetYawLocked( false );

	QAngle vecAngles = GetAbsAngles();
	vecAngles.z = 0.0f;
	GetOuter()->SetAbsAngles( vecAngles );

	// HACK: Will this work?
	IPhysicsObject *pPhysObj = GetOuter()->VPhysicsGetObject();
	if ( pPhysObj != NULL )
	{
		pPhysObj->EnableCollisions( true );
	}

	// Clear this
	m_PassengerIntent = PASSENGER_INTENT_NONE;
	SetPassengerState( PASSENGER_STATE_EXITING );

	// Get the velocity
	Vector vecUp, vecJumpDir;
	GetOuter()->GetVectors( &vecJumpDir, NULL, &vecUp );

	// Move back and up
	vecJumpDir *= random->RandomFloat( -400.0f, -500.0f );
	vecJumpDir += vecUp * 150.0f;
	GetOuter()->SetAbsVelocity( vecJumpDir );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAI_PolicingBehavior::RunTask( const Task_t *pTask )		
{ 
	switch ( pTask->iTask )
	{
	case TASK_POLICE_FACE_ALONG_GOAL:
		{
   			GetMotor()->UpdateYaw();
   
   			if ( GetOuter()->FacingIdeal() )
   			{
   				TaskComplete();
   			}
   			break;
		}

	default:
		BaseClass::RunTask( pTask);
	}
}
Esempio n. 4
0
void CASW_Parasite::DoJumpFromEgg()
{
	SetContextThink( NULL, gpGlobals->curtime, s_pParasiteAnimThink );
	SetParent( NULL );
	SetAbsOrigin( GetAbsOrigin() + Vector( 0, 0, 30 ) );	// TODO: position parasite at where his 'idle in egg' animation has him.  This has to be some distance off the ground, else the jump will immediately end.
	Vector dir = vec3_origin;
	AngleVectors( GetAbsAngles(), &dir );
	//Vector vecJumpPos = GetAbsOrigin()+ Vector(19,0,60)+ dir * m_flEggJumpDistance;
	Vector vecJumpPos = GetAbsOrigin() + dir * m_flEggJumpDistance;

	SetActivity( ACT_RANGE_ATTACK1 );
	StudioFrameAdvanceManual( 0.0 );
	SetParent( NULL );
	RemoveFlag( FL_FLY );
	AddEffects( EF_NOINTERP );
	m_bDoEggIdle = false;

	GetMotor()->SetIdealYaw( GetAbsAngles().y );

	JumpAttack( false, vecJumpPos, false );
}
Esempio n. 5
0
//=========================================================
// RunTask 
//=========================================================
void CNPC_Houndeye::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_HOUND_THREAT_DISPLAY:
		{
			GetMotor()->SetIdealYawToTargetAndUpdate( GetEnemyLKP(), AI_KEEP_YAW_SPEED );

			if ( IsActivityFinished() )
			{
				TaskComplete();
			}
			
			break;
		}
	case TASK_HOUND_CLOSE_EYE:
		{
			/*//<<TEMP>>
			if ( pev->skin < HOUNDEYE_EYE_FRAMES - 1 )
			{
				pev->skin++;
			}
			*/
			break;
		}
	case TASK_HOUND_HOP_BACK:
		{
			if ( IsActivityFinished() )
			{
				TaskComplete();
			}
			break;
		}
	default:
		{
			BaseClass::RunTask(pTask);
			break;
		}
	}
}
Esempio n. 6
0
//=========================================================
// Start task - selects the correct activity and performs
// any necessary calculations to start the next task on the
// schedule.  OVERRIDDEN for bullsquid because it needs to
// know explicitly when the last attempt to chase the enemy
// failed, since that impacts its attack choices.
//=========================================================
void CNPC_Bullsquid::StartTask ( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_MELEE_ATTACK2:
		{
			CPASAttenuationFilter filter( this );
			EmitSound( filter, entindex(), "Bullsquid.Growl" );		
			BaseClass::StartTask ( pTask );
			break;
		}
	case TASK_SQUID_HOPTURN:
		{
			SetActivity ( ACT_HOP );
			
			if ( GetEnemy() )
			{
				Vector	vecFacing = ( GetEnemy()->GetAbsOrigin() - GetAbsOrigin() );
				VectorNormalize( vecFacing );

				GetMotor()->SetIdealYaw( vecFacing );
			}

			break;
		}
	case TASK_SQUID_EAT:
		{
			m_flHungryTime = gpGlobals->curtime + pTask->flTaskData;
			break;
		}

	default:
		{
			BaseClass::StartTask ( pTask );
			break;
		}
	}
}
Esempio n. 7
0
AI_SuggestorResult_t CAI_PlaneSolver::GenerateObstacleSuggestion( const AILocalMoveGoal_t &goal, float yawScanCenter, 
																  float probeDist, float spanPerProbe, int probeOffset)
{
	AIMoveTrace_t moveTrace;
	float		  yawTest;
	float		  arcCenter;

	CalcYawsFromOffset( yawScanCenter, spanPerProbe, probeOffset, &yawTest, &arcCenter );

	Vector probeDir = UTIL_YawToVector( yawTest );
	float requiredMovement = goal.speed * GetMotor()->GetMoveInterval();

	// Probe immediate move with footing, then look further out ignoring footing
	bool fTraceClear = true;
	if ( probeDist > requiredMovement )
	{
		if ( !MoveLimit( goal.navType, GetLocalOrigin() + probeDir * requiredMovement, !ProbeForNpcs(), true, &moveTrace ) )
		{
			fTraceClear = false;
			moveTrace.flDistObstructed = (probeDist - requiredMovement) + moveTrace.flDistObstructed;
		}
	}

	if ( fTraceClear )
	{
		fTraceClear = MoveLimit( goal.navType, GetLocalOrigin() + probeDir * probeDist, !ProbeForNpcs(), false, &moveTrace );
	}
	

	if ( !fTraceClear )
	{
		GenerateSuggestionFromTrace( goal, moveTrace, probeDist, arcCenter, spanPerProbe, probeOffset );
		return SR_OK;
	}
	
	return SR_NONE;
}
//------------------------------------------------------------------------------
// Purpose: routine called every frame when a task is running
// Input  : pTask - the task structure
//------------------------------------------------------------------------------
void CAI_ASW_MeleeBehavior::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{
		case TASK_MELEE_FLIP_AROUND:
			{
				CBaseEntity *pTarget = GetEnemy();
				if ( pTarget )
				{
					GetMotor()->SetIdealYawAndUpdate( pTarget->GetAbsOrigin() - GetLocalOrigin(), AI_KEEP_YAW_SPEED );
				}

				if ( GetOuter()->IsActivityFinished() )
				{
					TaskComplete();
				}
			}
			break;

		default:
			BaseClass::RunTask( pTask );
			break;
	}
}
//-----------------------------------------------------------------------------
// 
//-----------------------------------------------------------------------------
void CNPC_Cremator::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_CREMATOR_IDLE:
		{
			SetActivity( ACT_IDLE );
			if( IsActivityFinished() )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_CREMATOR_RANGE_ATTACK1:
		{
			Vector flEnemyLKP = GetEnemyLKP();
			GetMotor()->SetIdealYawToTarget( flEnemyLKP );
			break;
		}
		default:
		BaseClass::StartTask( pTask );
		break;
	}
}
Esempio n. 10
0
//=========================================================
// SetYawSpeed - allows each sequence to have a different
// turn rate associated with it.
//=========================================================
void CNPC_HL1Barney::SetYawSpeed ( void )
{
	int ys;

	ys = 0;

	switch ( GetActivity() )
	{
	case ACT_IDLE:		
		ys = 70;
		break;
	case ACT_WALK:
		ys = 70;
		break;
	case ACT_RUN:
		ys = 90;
		break;
	default:
		ys = 70;
		break;
	}

	GetMotor()->SetYawSpeed( ys );
}
Esempio n. 11
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : flInterval - 
//			 - 
//			*pTraceResult - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CAI_BaseNPC::AutoMovement( float flInterval, CBaseEntity *pTarget, AIMoveTrace_t *pTraceResult )
{
	bool ignored;
	Vector newPos;
	QAngle newAngles;

	if (flInterval <= 0.0)
		return true;

	m_ScheduleState.bTaskRanAutomovement = true;

	if (GetIntervalMovement( flInterval, ignored, newPos, newAngles ))
	{
		// DevMsg( "%.2f : (%.1f) %.1f %.1f %.1f\n", gpGlobals->curtime, (newPos - GetLocalOrigin()).Length(), newPos.x, newPos.y, newAngles.y );
	
		if ( m_hCine )
		{
			m_hCine->ModifyScriptedAutoMovement( &newPos );
		}

		if (GetMoveType() == MOVETYPE_STEP)
		{
			if (!(GetFlags() & FL_FLY))
			{
				if ( !pTarget )
				{
					pTarget = GetNavTargetEntity();
				}

				// allow NPCs to adjust the automatic movement
				if ( ModifyAutoMovement( newPos ) )
				{
					// Set our motor's speed here
					Vector vecOriginalPosition = GetAbsOrigin();
					bool bResult = false;
					if (!TaskIsComplete())
					{
						bResult = ( GetMotor()->MoveGroundStep( newPos, pTarget, newAngles.y, false, true, pTraceResult ) == AIM_SUCCESS );
					}

					Vector change = GetAbsOrigin() - vecOriginalPosition;
					if (flInterval != 0)
					{
						change /= flInterval;
					}

					GetMotor()->SetMoveVel(change);

					return bResult;
				}

				return ( GetMotor()->MoveGroundStep( newPos, pTarget, newAngles.y, false, true, pTraceResult ) == AIM_SUCCESS );
			}
			else
			{
				// FIXME: here's no direct interface to a fly motor, plus this needs to support a state where going through the world is okay.
				// FIXME: add callbacks into the script system for validation
				// FIXME: add function on scripts to force only legal movements
				// FIXME: GetIntervalMovement deals in Local space, nor global.  Currently now way to communicate that through these interfaces.
				SetLocalOrigin( newPos );
				SetLocalAngles( newAngles );
				return true;
			}
		}
		else if (GetMoveType() == MOVETYPE_FLY)
		{
			Vector dist = newPos - GetLocalOrigin();

			VectorScale( dist, 1.0 / flInterval, dist );

			SetLocalVelocity( dist );
			return true;
		}
	}
	return false;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Output : int
//-----------------------------------------------------------------------------
int CNPC_Bug_Warrior::SelectSchedule( void )
{
	ClearCondition( COND_WBUG_STOP_FLEEING );

	// Turn towards sounds
	if ( HasCondition(COND_HEAR_DANGER) || HasCondition(COND_HEAR_COMBAT) )
	{
		CSound *pSound = GetBestSound();
		if ( pSound)
		{
			if ( !HasCondition( COND_SEE_ENEMY ) && ( pSound->m_iType & (SOUND_PLAYER | SOUND_COMBAT) ) )
			{
				GetMotor()->SetIdealYawToTarget( pSound->GetSoundReactOrigin() );
			}
		}
	}

	switch ( m_NPCState )
	{
	case NPC_STATE_IDLE:
		{
			// If I have an enemy, but I don't have any nearby friends, flee
			if ( HasCondition( COND_SEE_ENEMY ) && ShouldFlee() )
			{
				SetState( NPC_STATE_ALERT );
				return SCHED_WBUG_FLEE_ENEMY;
			}

			// Fellow bug might be requesting assistance
			if ( HasCondition( COND_WBUG_ASSIST_FELLOW_BUG ) )
				return SCHED_WBUG_ASSIST_FELLOW_BUG;

			// BugHole might be requesting help
			if ( HasCondition( COND_WBUG_RETURN_TO_BUGHOLE ) )
				return SCHED_WBUG_RETURN_TO_BUGHOLE;

			// Return to my bughole
			return SCHED_WBUG_RETURN_TO_BUGHOLE_AND_REMOVE;
			break;
		}
	case NPC_STATE_ALERT:
		{
			// If I have an enemy, but I don't have any nearby friends, flee
			if ( HasCondition( COND_SEE_ENEMY ) && ShouldFlee() )
			{
				SetState( NPC_STATE_ALERT );
				return SCHED_WBUG_FLEE_ENEMY;
			}

			// Fellow bug might be requesting assistance
			if ( HasCondition( COND_WBUG_ASSIST_FELLOW_BUG ) )
				return SCHED_WBUG_ASSIST_FELLOW_BUG;

			// BugHole might be requesting help
			if ( HasCondition( COND_WBUG_RETURN_TO_BUGHOLE ) )
				return SCHED_WBUG_RETURN_TO_BUGHOLE;

			// If I have a patrol path, walk it
			if ( m_iszPatrolPathName != NULL_STRING )
				return SCHED_WBUG_PATROL;

			break;
		}
	case NPC_STATE_COMBAT:
		{
			// Did I lose my enemy?
			if ( HasCondition ( COND_LOST_ENEMY ) || HasCondition ( COND_ENEMY_UNREACHABLE ) )
			{
				SetEnemy( NULL );
				m_bFightingToDeath = false;
				SetState(NPC_STATE_IDLE);
				return BaseClass::SelectSchedule();
			}

			// If I have an enemy, but I don't have any nearby friends, flee
			if ( HasCondition( COND_SEE_ENEMY ) && ShouldFlee() )
				return SCHED_WBUG_FLEE_ENEMY;

			// If we're able to melee, do so
			if ( HasCondition( COND_CAN_MELEE_ATTACK1 ) )
				return BaseClass::SelectSchedule();
		}
		break;
	}

	return BaseClass::SelectSchedule();
}
Esempio n. 13
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAI_FuncTankBehavior::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_FACE_FUNCTANK:
		{
			Assert( m_hFuncTank );

			GetMotor()->UpdateYaw();

			if ( GetOuter()->FacingIdeal() )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_HOLSTER_WEAPON:
		{
			Assert( m_hFuncTank );

			if ( GetOuter()->IsWeaponHolstered() )
			{
				GetOuter()->SpeakSentence( FUNCTANK_SENTENCE_JUST_MOUNTED );

				// We are at the correct position and facing for the func_tank, mount it.
				m_hFuncTank->StartControl( GetOuter() );
				GetOuter()->ClearEnemyMemory();
				m_bMounted = true;
				TaskComplete();

				GetOuter()->SetIdealActivity( ACT_IDLE_MANNEDGUN );
			}

			break;
		}
	case TASK_FIRE_FUNCTANK:
		{
			Assert( m_hFuncTank );

			if( GetOuter()->m_flWaitFinished < gpGlobals->curtime )
			{
				TaskComplete();
			}

			if ( m_hFuncTank->NPC_HasEnemy() )
			{
				GetOuter()->SetLastAttackTime( gpGlobals->curtime );
				m_hFuncTank->NPC_Fire();

				// The NPC may have decided to stop using the func_tank, because it's out of ammo.
				if ( !m_hFuncTank )
				{
					TaskComplete();
					break;
				}
			}
			else
			{
				TaskComplete();
			}
			
			Assert( m_hFuncTank );

			if ( m_hFuncTank->GetAmmoCount() == 0 )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_SCAN_LEFT_FUNCTANK:
	case TASK_SCAN_RIGHT_FUNCTANK:
		{
			GetMotor()->UpdateYaw();
			if ( GetOuter()->FacingIdeal() )
			{
				TaskComplete();
			}
			break;
		}
	case TASK_FORGET_ABOUT_FUNCTANK:
		{
			m_hFuncTank->NPC_InterruptRoute();
			SetBusy( gpGlobals->curtime + AI_FUNCTANK_BEHAVIOR_BUSYTIME );
			TaskComplete();
			break;
		}
	default:
		{
			BaseClass::RunTask( pTask );
			break;
		}
	}
}
void CAI_LeadBehavior::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
		case TASK_LEAD_FACE_GOAL:
		{
			if ( m_goalyaw != -1 )
			{
				GetMotor()->SetIdealYaw( m_goalyaw ); 
			}

			TaskComplete();
			break;
		}

		case TASK_LEAD_SUCCEED:
		{
			Speak( TLK_LEAD_SUCCESS );
			NotifyEvent( LBE_SUCCESS );

			break;
		}

		case TASK_LEAD_ARRIVE:
		{
			// Only speak the first time we arrive
			if ( !m_hasspokenarrival )
			{
				Speak( TLK_LEAD_ARRIVAL );
				NotifyEvent( LBE_ARRIVAL );

				m_hasspokenarrival = true;
			}
			else
			{
				TaskComplete();
			}
			
			break;
		}
		
		case TASK_STOP_LEADING:
		{
			ClearGoal();
			TaskComplete();
			break;
		}

		case TASK_GET_PATH_TO_LEAD_GOAL:
		{
			if ( GetNavigator()->SetGoal( m_goal ) )
			{
				TaskComplete();
			}
			else
			{
				TaskFail("NO PATH");
			}
			break;
		}
		
		case TASK_LEAD_GET_PATH_TO_WAITPOINT:
		{
			if ( GetNavigator()->SetGoal( m_waitpoint ) )
			{
				TaskComplete();
			}
			else
			{
				TaskFail("NO PATH");
			}
			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 ) ) )
			{
				ChainStartTask( TASK_RUN_PATH );
			}
			else
			{
				ChainStartTask( TASK_WALK_PATH );
			}
			break;
		}

		case TASK_LEAD_WAVE_TO_PLAYER:
		{
			// Wave to the player if we can see him. Otherwise, just idle.
			if ( HasCondition( COND_SEE_PLAYER ) )
			{
				Speak( TLK_LEAD_ATTRACTPLAYER );
				if ( HaveSequenceForActivity(ACT_SIGNAL1) )
				{
					SetActivity(ACT_SIGNAL1);
				}
			}
			else
			{
				SetActivity(ACT_IDLE);
			}

			TaskComplete();
			break;
		}

		case TASK_LEAD_PLAYER_NEEDS_WEAPON:
		{
			float flAvailableTime = GetOuter()->GetExpresser()->GetSemaphoreAvailableTime( GetOuter() );

			// if someone else is talking, don't speak
			if ( flAvailableTime <= gpGlobals->curtime )
			{
				Speak( TLK_LEAD_MISSINGWEAPON );
			}

			SetActivity(ACT_IDLE);
			TaskComplete();
			break;
		}

		case TASK_LEAD_SPEAK_START:
		{
			m_hasspokenstart = true;

			Speak( TLK_LEAD_START );
			SetActivity(ACT_IDLE);
			TaskComplete();
			break;
		}

		case TASK_LEAD_MOVE_TO_RANGE:
		{
			// If we haven't spoken our start speech, move closer
			if ( !m_hasspokenstart)
			{
				ChainStartTask( TASK_MOVE_TO_GOAL_RANGE, m_leaddistance - 24 );
			}
			else
			{
				ChainStartTask( TASK_MOVE_TO_GOAL_RANGE, m_retrievedistance );
			}
			break;
		}

		case TASK_LEAD_RETRIEVE_WAIT:
		{
			m_MoveMonitor.SetMark( AI_GetSinglePlayer(), 24 );
			ChainStartTask( TASK_WAIT_INDEFINITE );
			break;
		}

		case TASK_STOP_MOVING:
		{
			BaseClass::StartTask( pTask);

			if ( IsCurSchedule( SCHED_LEAD_PAUSE, false ) && pTask->flTaskData == 1 )
			{
				GetNavigator()->SetArrivalDirection( GetTarget() );
			}
			break;
		}

		case TASK_WAIT_FOR_SPEAK_FINISH:
		{
			BaseClass::StartTask( pTask);

			if( GetOuter()->GetState() == NPC_STATE_COMBAT )
			{
				// Don't stand around jabbering in combat. 
				TaskComplete();
			}

			// If we're not supposed to wait for the player, don't wait for speech to finish.
			// Instead, just wait a wee tad, and then start moving. NPC will speak on the go.
			if ( TaskIsRunning() && !m_args.iRetrievePlayer )
			{
				if ( gpGlobals->curtime - GetOuter()->GetTimeTaskStarted() > 0.3 )
				{
					TaskComplete();
				}
			}
			break;
		}

		default:
			BaseClass::StartTask( pTask);
	}
}
Esempio n. 15
0
//---------------------------------------------------------
//---------------------------------------------------------
void CNPC_Dog::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{

	case TASK_DOG_PICKUP_ITEM:
	{
		 PullObject( false );
	}
	break;

	case TASK_DOG_GET_PATH_TO_PHYSOBJ:
		{
			//Check this cause our object might have been deleted.
			if ( m_hPhysicsEnt == NULL )
				 FindPhysicsObject( NULL );

			//And if we still can't find anything, then just go away.
			if ( m_hPhysicsEnt == NULL )
			{
				TaskFail( "Can't find an object I like!" );
				return;
			}
	
			IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject();
			
			Vector vecGoalPos;
			Vector vecDir;

			vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
			VectorNormalize(vecDir);
			vecDir.z = 0;
		
			if ( m_hPhysicsEnt->GetOwnerEntity() == NULL )
				 m_hPhysicsEnt->SetOwnerEntity( this );
		
			if ( pPhysicsObject )
				 pPhysicsObject->RecheckCollisionFilter();

			vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

			bool bBuiltRoute = false;

			//If I'm near my goal, then just walk to it.
			Activity aActivity = ACT_RUN;

			if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
				 aActivity = ACT_WALK;

			bBuiltRoute = GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL );

			if ( bBuiltRoute == true )
				 TaskComplete();
			else
			{
				m_flTimeToCatch = gpGlobals->curtime + 0.1;
				m_flNextRouteTime = gpGlobals->curtime + 0.3;
				m_flNextSwat = gpGlobals->curtime + 0.1;

				if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 )
					 m_hUnreachableObjects.AddToTail( m_hPhysicsEnt );
								
				m_hPhysicsEnt = NULL;

				GetNavigator()->ClearGoal();
			}
		}
		break;

	case TASK_WAIT:
	{
		if ( IsWaitFinished() )
		{
			TaskComplete();
		}

		if ( m_hPhysicsEnt )
		{
			if ( m_bHasObject == false )
			{
				GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() );
				GetMotor()->UpdateYaw();
			}
		}

		break;
	}

	case TASK_DOG_LAUNCH_ITEM:
		if( IsActivityFinished() )
		{
			if ( m_hPhysicsEnt )
			{
				m_hPhysicsEnt->SetOwnerEntity( NULL );
			}

			TaskComplete();
		}
		break;

	case TASK_DOG_WAIT_FOR_TARGET_TO_FACE:
	{
		if ( CanTargetSeeMe() )
			 TaskComplete();
	}
		break;

	case TASK_WAIT_FOR_MOVEMENT:
		{
			if ( GetState() == NPC_STATE_SCRIPT || IsInAScript() )
			{
			  	 BaseClass::RunTask( pTask );
				 return;
			}

			if ( m_hPhysicsEnt != NULL )
			{
				IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();
					
				if ( !pPhysObj )
				{
					Warning( "npc_dog TASK_WAIT_FOR_MOVEMENT with NULL m_hPhysicsEnt->VPhysicsGetObject\n" );
				}

				if ( pPhysObj && pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
					 TaskFail( "Player picked it up!" );

				//If the object is moving then my old goal might not be valid
				//cancel the schedule and make it restart again in a bit.
				if ( pPhysObj && pPhysObj->IsAsleep() == false && GetNavigator()->IsGoalActive() == false )
				{
					Vector vecGoalPos;
					Vector vecDir;
				
					vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
					VectorNormalize(vecDir);
					vecDir.z = 0;
									
					vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

					GetNavigator()->ClearGoal();

					float flDistance = (vecGoalPos - GetLocalOrigin()).Length();

					//If I'm near my goal, then just walk to it.
					Activity aActivity = ACT_RUN;

					if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
						 aActivity = ACT_WALK;

				    GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL );

					if ( flDistance <= DOG_PHYSOBJ_MOVE_TO_DIST )
					{
						TaskComplete();
						GetNavigator()->StopMoving();
					}
				}
			}
			
			BaseClass::RunTask( pTask );
		}
		break;

	case TASK_DOG_WAIT_FOR_OBJECT:
		{
			if ( m_hPhysicsEnt != NULL )
			{
				if ( FVisible( m_hPhysicsEnt ) == false )
				{
					m_flTimeToCatch = 0.0f;
					ClearBeams();
					TaskFail( "Lost sight of the object!" );
					m_hPhysicsEnt->SetOwnerEntity( NULL );
					return;
				}

				m_hPhysicsEnt->SetOwnerEntity( this );

				Vector vForward;
				AngleVectors( GetAbsAngles(), &vForward );


				Vector vGunPos;
				GetAttachment( m_iPhysGunAttachment, vGunPos );

				Vector vToObject = m_hPhysicsEnt->WorldSpaceCenter() - vGunPos;
				float flDistance = vToObject.Length();

				VectorNormalize( vToObject );

				SetAim( m_hPhysicsEnt->WorldSpaceCenter() - GetAbsOrigin() );

				#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
					CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this); 
				#else
					CBasePlayer *pPlayer = AI_GetSinglePlayer();
				#endif //SecobMod__Enable_Fixed_Multiplayer_AI

				float flDistanceToPlayer = flDistance;

				if ( pPlayer )
				{
					flDistanceToPlayer = (pPlayer->GetAbsOrigin() - m_hPhysicsEnt->WorldSpaceCenter()).Length();
				}
			
				IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();
				if ( !pPhysObj )
				{
					Warning( "npc_dog:  TASK_DOG_WAIT_FOR_OBJECT with m_hPhysicsEnt->VPhysicsGetObject == NULL\n" );
				}
					
				if ( pPhysObj && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) && flDistanceToPlayer > ( flDistance * 2 ) )
				{
					if ( m_flTimeToPull <= gpGlobals->curtime )
					{
						Vector vCurrentVel;
						float flCurrentVel;
						AngularImpulse vCurrentAI;

						pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI );

						flCurrentVel = vCurrentVel.Length();
						VectorNormalize( vCurrentVel );

						if ( pPhysObj && flDistance <= DOG_PULL_DISTANCE )
						{
							Vector vDir = ( vGunPos -  m_hPhysicsEnt->WorldSpaceCenter() );
								
							VectorNormalize( vDir );

							vCurrentVel = vCurrentVel * ( flCurrentVel * DOG_PULL_VELOCITY_MOD );

							vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD;
							pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI );

							vDir = vDir * flDistance * DOG_PULL_TO_GUN_VEL_MOD;

							Vector vAngle( 0, 0, 0 );
							pPhysObj->AddVelocity( &vDir, &vAngle );
							
							CreateBeams();
						}
					
						float flDot = DotProduct( vCurrentVel, vForward );

						if ( flDistance >= DOG_PULL_DISTANCE && flDistance <= ( DOG_PULL_DISTANCE * 2 ) && flDot > -0.3 )
						{
							if ( pPhysObj->IsAsleep() == false && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) )
							{
								Vector vecGoalPos;
								Vector vecDir;

								vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
								VectorNormalize(vecDir);
								vecDir.z = 0;
												
								vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

								GetNavigator()->ClearGoal();

								//If I'm near my goal, then just walk to it.
								Activity aActivity = ACT_RUN;

								if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
									 aActivity = ACT_WALK;
									 
								GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ),  AIN_NO_PATH_TASK_FAIL );
							}
						}
					}
				}


				float flDirDot = DotProduct( vToObject, vForward );

				if ( flDirDot < 0.2 )
				{
					GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() );
					GetMotor()->UpdateYaw();
				}

				if ( m_flTimeToCatch < gpGlobals->curtime && m_bDoWaitforObjectBehavior == false ) 
				{
					m_hPhysicsEnt->SetOwnerEntity( NULL );
					m_flTimeToCatch = 0.0f;
					ClearBeams();
					TaskFail( "Done waiting!" );
				}
				else if ( pPhysObj && ( flDistance <= DOG_CATCH_DISTANCE && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) )
				{
					AngularImpulse vZero( 0, 0, 0 );
					pPhysObj->SetVelocity( &vec3_origin, &vZero );

					GetNavigator()->StopMoving();

					//Fire Output!
					m_OnCatch.FireOutput( this, this );
					m_bHasObject = true;
					ClearBeams();
					TaskComplete();
				}
			}
			else
			{
				GetNavigator()->StopMoving();

				ClearBeams();
				TaskFail("No Physics Object!");
			}
			
		}
		break;

	case TASK_DOG_CATCH_OBJECT:
		if( IsActivityFinished() )
		{
			m_flTimeToCatch = 0.0f;
			TaskComplete();
		}
		break;
	default:
		BaseClass::RunTask( pTask );
		break;
	}
}
// Основная атака огнеметом
// This is the cremator's main attack, or more precisely, its damage function.
void CNPC_Cremator::DispatchSpray( CBaseEntity *pEntity )
{ 
	Vector vecSrc, vecAim;
	trace_t tr;	

	//const char *entityname = pEntity->GetClassname();

	Vector forward, right, up;
	AngleVectors( GetAbsAngles(), &forward, &right, &up );

	vecSrc = GetAbsOrigin() + up * 36;
	vecAim = GetShootEnemyDir( vecSrc );
	float deflection = 0.01;	
	vecAim = vecAim + 1 * right * random->RandomFloat( 0, deflection ) + up * random->RandomFloat( -deflection, deflection );
	UTIL_TraceLine ( vecSrc, vecSrc + vecAim * 512, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);
			
/*	if ( tr.DidHitWorld() ) // spawn flames on solid surfaces. 
							// It's not very important since it is extremely rare for a cremator to
							// hit brush geometry but might be a nice feature for a close-space combat
							// it also works fine but again is EXTREMELY hard to get in-game
	{
		Vector	ofsDir = ( tr.endpos - GetAbsOrigin() );
		float	offset = VectorNormalize( ofsDir );

		if ( offset > 128 )
			offset = 128;

		float scale	 = 0.1f + ( 0.75f * ( 1.0f - ( offset / 128.0f ) ) );
		float growth = 0.1f + ( 0.75f * (offset / 128.0f ) );

		if ( tr.surface.flags & CONTENTS_GRATE ) // get smaller flames on grates since they have a smaller burning area
		{
			scale = 0.1f + ( 0.15f * ( 1.0f - ( offset / 128.0f ) ) );
		}
		else
		{
			scale = 0.1f + ( 0.75f * ( 1.0f - ( offset / 128.0f ) ) );
		}
		FireSystem_StartFire( tr.endpos, scale, growth, 8.0, 10.0f, (SF_FIRE_START_ON|SF_FIRE_START_FULL), (CBaseEntity*) this, FIRE_NATURAL );

	}	
*/

	pEntity = tr.m_pEnt;

	if ( pEntity != NULL && m_takedamage )
	{
		CTakeDamageInfo firedamage( this, this, sk_cremator_firedamage.GetFloat(), DMG_BURN );
		CTakeDamageInfo radiusdamage( this, this, sk_cremator_radiusdamage.GetFloat(), DMG_PLASMA ); 
		CalculateMeleeDamageForce( &firedamage, vecAim, tr.endpos );
		RadiusDamage ( CTakeDamageInfo ( this, this, 2, DMG_PLASMA ), // AOE; this stuff makes cremators absurdly powerfull sometimes btw
			tr.endpos,
			64.0f,
			CLASS_NONE,
			NULL );

		pEntity->DispatchTraceAttack( ( firedamage ), vecAim, &tr );
		
		Vector flEnemyLKP = pEntity->GetAbsOrigin();
		GetMotor()->SetIdealYawToTargetAndUpdate( flEnemyLKP );

		ClearMultiDamage();
	}	

	m_iAmmo --;
}
Esempio n. 17
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pTask - 
//-----------------------------------------------------------------------------
void CAI_AssaultBehavior::StartTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{
	case TASK_RANGE_ATTACK1:
		BaseClass::StartTask( pTask );
		break;

	case TASK_ASSAULT_DEFER_SCHEDULE_SELECTION:
		m_flTimeDeferScheduleSelection = gpGlobals->curtime + pTask->flTaskData;
		TaskComplete();
		break;

	case TASK_ASSAULT_MOVE_AWAY_PATH:
		break;

	case TASK_ANNOUNCE_CLEAR:
		{
			// If we're at an assault point that can never be cleared, keep waiting forever (if it's the last point in the assault)
			if ( m_hAssaultPoint && 
				 !m_hAssaultPoint->HasSpawnFlags( SF_ASSAULTPOINT_CLEARONARRIVAL ) &&
				 m_hAssaultPoint->m_bNeverTimeout && 
				 m_hAssaultPoint->m_NextAssaultPointName == NULL_STRING )
			{
				TaskComplete();
				return;
			}

			ClearAssaultPoint();
			TaskComplete();
		}
		break;

	case TASK_WAIT_ASSAULT_DELAY:
		{
			if( m_hRallyPoint )
			{
				GetOuter()->SetWait( m_hRallyPoint->m_flAssaultDelay );
			}
			else
			{
				TaskComplete();
			}
		}
		break;

	case TASK_AWAIT_ASSAULT_TIMEOUT:
		// Maintain vigil for as long as the level designer has asked. Wait
		// and look for targets.
		GetOuter()->SetWait( m_hAssaultPoint->m_flAssaultTimeout );
		break;

	case TASK_GET_PATH_TO_RALLY_POINT:
		{
			AI_NavGoal_t goal( m_hRallyPoint->GetAbsOrigin() );
			goal.pTarget = m_hRallyPoint;
			if ( GetNavigator()->SetGoal( goal ) == false )
			{
				// Try and get as close as possible otherwise
				AI_NavGoal_t nearGoal( GOALTYPE_LOCATION_NEAREST_NODE, m_hRallyPoint->GetAbsOrigin(), AIN_DEF_ACTIVITY, 256 );
				if ( GetNavigator()->SetGoal( nearGoal, AIN_CLEAR_PREVIOUS_STATE ) )
				{
					//FIXME: HACK! The internal pathfinding is setting this without our consent, so override it!
					ClearCondition( COND_TASK_FAILED );
					GetNavigator()->SetArrivalDirection( m_hRallyPoint->GetAbsAngles() );
					TaskComplete();
					return;
				}
			}
			GetNavigator()->SetArrivalDirection( m_hRallyPoint->GetAbsAngles() );
		}
		break;

	case TASK_FACE_RALLY_POINT:
		{
			UpdateForceCrouch();
			
			GetMotor()->SetIdealYaw( m_hRallyPoint->GetAbsAngles().y );
			GetOuter()->SetTurnActivity(); 
		}
		break;

	case TASK_GET_PATH_TO_ASSAULT_POINT:
		{
			AI_NavGoal_t goal( m_hAssaultPoint->GetAbsOrigin() );
			goal.pTarget = m_hAssaultPoint;
			if ( GetNavigator()->SetGoal( goal ) == false )
			{
				// Try and get as close as possible otherwise
				AI_NavGoal_t nearGoal( GOALTYPE_LOCATION_NEAREST_NODE, m_hAssaultPoint->GetAbsOrigin(), AIN_DEF_ACTIVITY, 256 );
				if ( GetNavigator()->SetGoal( nearGoal, AIN_CLEAR_PREVIOUS_STATE ) )
				{
					//FIXME: HACK! The internal pathfinding is setting this without our consent, so override it!
					ClearCondition( COND_TASK_FAILED );
					GetNavigator()->SetArrivalDirection( m_hAssaultPoint->GetAbsAngles() );
					TaskComplete();
					return;
				}
			}
			GetNavigator()->SetArrivalDirection( m_hAssaultPoint->GetAbsAngles() );
		}
		break;

	case TASK_FACE_ASSAULT_POINT:
		{
			UpdateForceCrouch();

			if( HasCondition( COND_CAN_RANGE_ATTACK1 ) )
			{
				// If I can already fight when I arrive, don't bother running any facing code. Let
				// The combat AI do that. Turning here will only make the NPC look dumb in a combat
				// situation because it will take time to turn before attacking.
				TaskComplete();
			}
			else
			{
				GetMotor()->SetIdealYaw( m_hAssaultPoint->GetAbsAngles().y );
				GetOuter()->SetTurnActivity(); 
			}
		}
		break;

	case TASK_HIT_ASSAULT_POINT:
		OnHitAssaultPoint();
		TaskComplete();
		break;

	case TASK_HIT_RALLY_POINT:
		// Once we're stading on it and facing the correct direction,
		// we have arrived at rally point.
		GetOuter()->SpeakSentence( ASSAULT_SENTENCE_HIT_RALLY_POINT );

		m_bHitRallyPoint = true;
		m_hRallyPoint->m_OnArrival.FireOutput( GetOuter(), m_hRallyPoint, 0 );

		TaskComplete();
		break;

	case TASK_AWAIT_CUE:
		if( PollAssaultCue() )
		{
			TaskComplete();
		}
		else
		{
			// Don't do anything if we've been told to crouch
			if ( IsForcingCrouch() )
				break;

			else if( m_hRallyPoint->m_RallySequenceName != NULL_STRING )
			{
				// The cue hasn't been given yet, so set to the rally sequence.
				int sequence = GetOuter()->LookupSequence( STRING( m_hRallyPoint->m_RallySequenceName ) );
				if( sequence != -1 )
				{
					GetOuter()->ResetSequence( sequence );
					GetOuter()->SetIdealActivity( ACT_DO_NOT_DISTURB );
				}
			}
			else
			{
				// Only chain this task if I'm not playing a custom animation
				if( GetOuter()->GetEnemy() )
				{
					ChainStartTask( TASK_FACE_ENEMY, 0 );
				}
			}
		}
		break;

	default:
		BaseClass::StartTask( pTask );
		break;
	}
}
//=========================================================
// RunTask 
//=========================================================
void CNPC_Controller::RunTask ( const Task_t *pTask )
{
	if (m_flShootEnd > gpGlobals->curtime)
	{
		Vector vecHand;
		QAngle vecAngle;
		
		GetAttachment( 2, vecHand, vecAngle );
	
		while (m_flShootTime < m_flShootEnd && m_flShootTime < gpGlobals->curtime)
		{
			Vector vecSrc = vecHand + GetAbsVelocity() * (m_flShootTime - gpGlobals->curtime);
			Vector vecDir;
			
			if (GetEnemy() != NULL)
			{
				if (HasCondition( COND_SEE_ENEMY ))
				{
					m_vecEstVelocity = m_vecEstVelocity * 0.5 + GetEnemy()->GetAbsVelocity() * 0.5;
				}
				else
				{
					m_vecEstVelocity = m_vecEstVelocity * 0.8;
				}
				vecDir = Intersect( vecSrc, GetEnemy()->BodyTarget( GetAbsOrigin() ), m_vecEstVelocity, sk_controller_speedball.GetFloat() );
			
				float delta = 0.03490; // +-2 degree
				vecDir = vecDir + Vector( random->RandomFloat( -delta, delta ), random->RandomFloat( -delta, delta ), random->RandomFloat( -delta, delta ) ) * sk_controller_speedball.GetFloat();

				vecSrc = vecSrc + vecDir * (gpGlobals->curtime - m_flShootTime);
				CAI_BaseNPC *pBall = (CAI_BaseNPC*)Create( "controller_energy_ball", vecSrc, GetAbsAngles(), this );
				pBall->SetAbsVelocity( vecDir );

//				DevMsg( 2, "controller shooting energy ball\n" );
			}
			
			m_flShootTime += 0.2;
		}

		if (m_flShootTime > m_flShootEnd)
		{
			m_iBall[0] = 64;
			m_iBallTime[0] = m_flShootEnd;
			m_iBall[1] = 64;
			m_iBallTime[1] = m_flShootEnd;
			m_fInCombat = FALSE;
		}
	}

	switch ( pTask->iTask )
	{
	case TASK_WAIT_FOR_MOVEMENT:
	case TASK_WAIT:
	case TASK_WAIT_FACE_ENEMY:
	case TASK_WAIT_PVS:
		{
			if( GetEnemy() )
			{
				float idealYaw = UTIL_VecToYaw( GetEnemy()->GetAbsOrigin() - GetAbsOrigin() );
				GetMotor()->SetIdealYawAndUpdate( idealYaw );
			}

			if ( IsSequenceFinished() || GetActivity() == ACT_IDLE)
			{
				m_fInCombat = false;
			}

			BaseClass::RunTask ( pTask );

			if (!m_fInCombat)
			{
				if( HasCondition( COND_CAN_RANGE_ATTACK1 ))
				{
					SetActivity( ACT_RANGE_ATTACK1 );
					SetCycle( 0 ); 
					ResetSequenceInfo( );
					m_fInCombat = true;
				}
				else if( HasCondition( COND_CAN_RANGE_ATTACK2 ) )
				{
					SetActivity( ACT_RANGE_ATTACK2 );
					SetCycle( 0 );
					ResetSequenceInfo( );
					m_fInCombat = true;
				}
				else
				{
					int iFloatActivity = LookupFloat();
					if( IsSequenceFinished() || iFloatActivity != GetActivity() )
					{
						SetActivity( (Activity)iFloatActivity );
					}
				}
			}
		}
		break;
	default: 
		BaseClass::RunTask ( pTask );
		break;
	}
}
Esempio n. 19
0
//---------------------------------------------------------
//---------------------------------------------------------
void CNPC_Dog::StartTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{

	case TASK_DOG_SETUP_THROW_TARGET:
		{
			SetupThrowTarget();
			TaskComplete();
		}
		break;
	case TASK_DOG_GET_PATH_TO_PHYSOBJ:
		{
			FindPhysicsObject( STRING( m_sObjectName ) );

			if ( m_hPhysicsEnt == NULL )
			{
				 FindPhysicsObject( NULL );
				 return;
			}

			IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject();
			
			Vector vecGoalPos;
			Vector vecDir;

			vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter();
			VectorNormalize(vecDir);
			vecDir.z = 0;
		
			if ( m_hPhysicsEnt->GetOwnerEntity() == NULL )
				 m_hPhysicsEnt->SetOwnerEntity( this );
		
			if ( pPhysicsObject )
				 pPhysicsObject->RecheckCollisionFilter();

			vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST );

			//If I'm near my goal, then just walk to it.
			Activity aActivity = ACT_RUN;

			if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 )
				 aActivity = ACT_WALK;

			if ( GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ) == false )
			{
				 if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 )
					  m_hUnreachableObjects.AddToTail( m_hPhysicsEnt );
					
				 FindPhysicsObject( NULL, m_hPhysicsEnt );

				 m_flTimeToCatch = gpGlobals->curtime + 0.1;
				 m_flNextRouteTime = gpGlobals->curtime + 0.3;
				 m_flNextSwat = gpGlobals->curtime + 0.1;

				 GetNavigator()->ClearGoal();
			}
			else
			{
				TaskComplete();
			}
		}
		break;

	case TASK_DOG_FACE_OBJECT:
		{
			if( m_hPhysicsEnt == NULL )
			{
				// Physics Object is gone! Probably was an explosive 
				// or something else broke it.
				TaskFail("Physics ent NULL");
				return;
			}

			Vector vecDir;

			vecDir = m_hPhysicsEnt->WorldSpaceCenter() - GetLocalOrigin();
			VectorNormalize(vecDir);

			GetMotor()->SetIdealYaw( UTIL_VecToYaw( vecDir ) );
			TaskComplete();
		}
		break;
		
	case TASK_DOG_PICKUP_ITEM:
		{
			if( m_hPhysicsEnt == NULL )
			{
				// Physics Object is gone! Probably was an explosive 
				// or something else broke it.
				TaskFail("Physics ent NULL");
				return;
			}
			else
			{
				SetIdealActivity( (Activity)ACT_DOG_PICKUP );
			}
		}

		break;
		
	case TASK_DOG_LAUNCH_ITEM:
		{
			if( m_hPhysicsEnt == NULL )
			{
				// Physics Object is gone! Probably was an explosive 
				// or something else broke it.
				TaskFail("Physics ent NULL");
				return;
			}
			else
			{
				if ( m_hPhysicsEnt == NULL || m_bHasObject == false )
				{
					 TaskFail( "Don't have the item!" );
					 return;
				}

				SetIdealActivity( (Activity)ACT_DOG_THROW );
			}
		}

		break;

	case TASK_DOG_WAIT_FOR_TARGET_TO_FACE:
		{
			if ( CanTargetSeeMe() )
				 TaskComplete();
		}
		break;

	case TASK_DOG_WAIT_FOR_OBJECT:
		{
			SetIdealActivity( (Activity)ACT_DOG_WAITING );
		}
		break;

	case TASK_DOG_CATCH_OBJECT:
	{
		SetIdealActivity( (Activity)ACT_DOG_CATCH  );
	}
	break;
			
	case TASK_DOG_DELAY_SWAT:
		m_flNextSwat = gpGlobals->curtime + pTask->flTaskData;

		if ( m_hThrowTarget == NULL )
		#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
			m_hThrowTarget = UTIL_GetNearestVisiblePlayer(this); 
		#else
			m_hThrowTarget = AI_GetSinglePlayer();
		#endif //SecobMod__Enable_Fixed_Multiplayer_AI

		TaskComplete();
		break;

	default:
		BaseClass::StartTask( pTask );
	}
}
void CNPC_BigMomma::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_CHECK_NODE_PROXIMITY:
		{

		}

		break;
	case TASK_FIND_NODE:
		{
			CBaseEntity *pTarget = GetTarget();

			if ( !HasMemory( bits_MEMORY_ADVANCE_NODE ) )
			{
				if ( pTarget )
					 m_iszTarget = pTarget->m_target;
			}

			NodeStart( m_iszTarget );
			TaskComplete();
			//Msg( "BM: Found node %s\n", STRING( m_iszTarget ) );
		}
		break;

	case TASK_NODE_DELAY:
		m_nodeTime = gpGlobals->curtime + pTask->flTaskData;
		TaskComplete();
		//Msg( "BM: FAIL! Delay %.2f\n", pTask->flTaskData );
		break;

	case TASK_PROCESS_NODE:
		//Msg( "BM: Reached node %s\n", STRING( m_iszTarget ) );
		NodeReach();
		TaskComplete();
		break;

	case TASK_PLAY_NODE_PRESEQUENCE:
	case TASK_PLAY_NODE_SEQUENCE:
		{
			const char *pSequence = NULL;
			int	iSequence;

			if ( pTask->iTask == TASK_PLAY_NODE_SEQUENCE )
				pSequence = GetNodeSequence();
			else
				pSequence = GetNodePresequence();

			//Msg( "BM: Playing node sequence %s\n", pSequence );

			if ( pSequence ) //ugh
			{
				iSequence = LookupSequence( pSequence );

				if ( iSequence != -1 )
				{
					SetIdealActivity( ACT_DO_NOT_DISTURB );
					SetSequence( iSequence );
					SetCycle( 0.0f );

					ResetSequenceInfo();
					//Msg( "BM: Sequence %s %f\n", GetNodeSequence(), gpGlobals->curtime );
					return;
				}
			}
			TaskComplete();
		}
		break;

	case TASK_NODE_YAW:
		GetMotor()->SetIdealYaw( GetNodeYaw() );
		TaskComplete();
		break;

	case TASK_WAIT_NODE:
		m_flWait = gpGlobals->curtime + GetNodeDelay();

		/*if ( GetTarget() && GetTarget()->GetSpawnFlags() & SF_INFOBM_WAIT )
			Msg( "BM: Wait at node %s forever\n", STRING( m_iszTarget) );
		else
			Msg( "BM: Wait at node %s for %.2f\n", STRING( m_iszTarget ), GetNodeDelay() );*/
		break;


	case TASK_MOVE_TO_NODE_RANGE:
		{
			CBaseEntity *pTarget = GetTarget();

			if ( !pTarget )
				TaskFail( FAIL_NO_TARGET );
			else
			{
				if ( ( pTarget->GetAbsOrigin() - GetAbsOrigin() ).Length() < GetNodeRange() )
					TaskComplete();
				else
				{
					Activity act = ACT_WALK;
					if ( pTarget->GetSpawnFlags() & SF_INFOBM_RUN )
						 act = ACT_RUN;

					AI_NavGoal_t goal( GOALTYPE_TARGETENT, vec3_origin, act );

					if ( !GetNavigator()->SetGoal( goal ) )
					{
						TaskFail( NO_TASK_FAILURE );
					}
				}
			}
		}
		//Msg( "BM: Moving to node %s\n", STRING( m_iszTarget ) );

		break;

	case TASK_MELEE_ATTACK1:
		{

		// Play an attack sound here

			CPASAttenuationFilter filter( this );
			EmitSound( filter, entindex(), "BigMomma.Attack" );

			BaseClass::StartTask( pTask );
		}
		
		break;

	default: 
		BaseClass::StartTask( pTask );
		break;
	}
}
Esempio n. 21
0
//-----------------------------------------------------------------------------
// 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;
	}
}
//------------------------------------------------------------------------------
// Purpose: routine called every frame when a task is running
// Input  : pTask - the task structure
//------------------------------------------------------------------------------
void CAI_ASW_ShieldBehavior::RunTask( const Task_t *pTask )
{
	switch( pTask->iTask )
	{
		case TASK_SHIELD_RAISE:
			{
				CBaseEntity *pTarget = GetEnemy();

				if ( pTarget )
				{
					GetMotor()->SetIdealYawAndUpdate( pTarget->GetAbsOrigin() - GetLocalOrigin(), AI_KEEP_YAW_SPEED );
				}

				if ( GetOuter()->IsActivityFinished() )
				{
					TaskComplete();
					SetBehaviorParam( m_StatusParm, 1 );
				}
			}		
			break;

		case TASK_SHIELD_LOWER:
			if ( GetOuter()->IsActivityFinished() )
			{
				TaskComplete();
				SetBehaviorParam( m_StatusParm, 0 );
				m_bShieldLowering = false;
			}
			break;

		case TASK_SHIELD_MAINTAIN:
			{
				bool			bNoReset = false;

				if ( m_TurningGesture != ACT_INVALID )
				{
					CBaseEntity		*pTarget = GetEnemy();

					if ( pTarget )
					{
						GetMotor()->SetIdealYawAndUpdate( pTarget->GetAbsOrigin() - GetLocalOrigin(), AI_KEEP_YAW_SPEED );
					}

					if ( GetOuter()->IsPlayingGesture( m_TurningGesture ) == false )
					{
						TaskComplete();
						m_TurningGesture = ACT_INVALID;

						if ( pTarget )
						{
							float flIdealYaw = UTIL_VecToYaw( pTarget->GetAbsOrigin() - GetLocalOrigin() );
							float flYawDiff = UTIL_AngleMod( GetLocalAngles().y - flIdealYaw );
							if ( flYawDiff > 25.0f && flYawDiff < 335.0f )
							{
								bNoReset = true;
							}
						}
					}
				}
				else if ( GetOuter()->IsActivityFinished() )
				{
					TaskComplete();
				}

				if ( m_flStartFrozenTime != -1.0f && m_flEndFrozenTime < gpGlobals->curtime && bNoReset == false )
				{
					m_flStartFrozenTime = -1.0f;
					m_flStartDownTime = gpGlobals->curtime + m_flSFrozenDownTime;
					SetBehaviorParam( m_FrozenParm, 0 );
				}
			}
			break;

		case TASK_SHIELD_MAINTAIN_FLIP:
			{
				CBaseEntity *pTarget = GetEnemy();
				if ( pTarget )
				{
					GetMotor()->SetIdealYawAndUpdate( pTarget->GetAbsOrigin() - GetLocalOrigin(), AI_KEEP_YAW_SPEED );
				}

				if ( GetOuter()->IsActivityFinished() )
				{
					TaskComplete();
				}
			}
			break;

		default:
			BaseClass::RunTask( pTask );
			break;
	}
}
// Здесь происходит назначение различных ф-ций во время анимации. Аним-ивенты назначаются в .qc.
void CNPC_Cremator::HandleAnimEvent( animevent_t *pEvent )
{
	switch( pEvent->event )
	{
		case CREMATOR_AE_FLLEFT: // левый шаг
			{	
				LeftFootHit( pEvent->eventtime );
			}
			break;

		case CREMATOR_AE_FLRIGHT: // правый шаг
			{				
				RightFootHit( pEvent->eventtime );
			}
			break;

		case CREMATOR_AE_IMMO_START: // начало анимации атаки
			{
				//CBaseEntity *pEntity;

				DispatchSpray( this );
				DevMsg( "%i ammo left\n", m_iAmmo );

				Vector flEnemyLKP = GetEnemyLKP();
				GetMotor()->SetIdealYawToTargetAndUpdate( flEnemyLKP );
			}
			break;

		case CREMATOR_AE_IMMO_PARTICLE: // Маркер для запуска системы частиц огнемета
			{				
				DispatchParticleEffect( "flamethrower", PATTACH_POINT_FOLLOW, this, "muzzle" ); 
				// Если нужно заменить зеленый огонь оранжевым, замени "flamethrower" на "flamethrower_orange".
				EmitSound( "Weapon_Immolator.Single" );
			}
			break;

		case CREMATOR_AE_IMMO_PARTICLEOFF: // Маркер для отключения системы частиц огнемета
			{				
				StopParticleEffects( this );
				StopSound( "Weapon_Immolator.Single" );
				EmitSound( "Weapon_Immolator.Stop" );
			}
			break;

		case CREMATOR_AE_RELOAD:
			{
				ClearCondition( COND_CREMATOR_OUT_OF_AMMO );
				ClearCondition( COND_NO_PRIMARY_AMMO );
				m_iAmmo += 54; // Put your own int here. This defines for how long a cremator would be able to fire at an enemy.
				
				DevMsg( "AE_RELOAD\n" );
			}
			break;

		case CREMATOR_AE_THROWGRENADE: // Маркер для броска гранаты
			{				
				DevMsg( "Throwing incendiary grenade!\n" );
				ThrowIncendiaryGrenade();

				if( g_pGameRules->IsSkillLevel(SKILL_EASY) )
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat( 15.0f, 30.0f );
				}
				else if( g_pGameRules->IsSkillLevel(SKILL_HARD) )
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat( 5.0f, 10.0f );
				}
				else if (g_pGameRules->IsSkillLevel(SKILL_VERYHARD))
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat(3.0f, 5.0f);
				}
				else if (g_pGameRules->IsSkillLevel(SKILL_NIGHTMARE))
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat(1.0f, 3.0f);
				}
				else
				{
					m_flNextRangeAttack2Time = gpGlobals->curtime + random->RandomFloat( 10.0f, 20.0f );
				}
			}
			break;

		default:
			BaseClass::HandleAnimEvent( pEvent );
			break;
	}
}
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;
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pTask - 
//-----------------------------------------------------------------------------
void CNPC_Bug_Builder::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_BBUG_GET_PATH_TO_FLEE:
		{
			// Always tell our bughole that we're under attack
			if ( m_hMyBugHole )
			{
				m_hMyBugHole->IncomingFleeingBug( this );
			}

			// If we have no squad, or we couldn't get a path to our squadmate, move to our bughole
			if ( m_hMyBugHole )
			{
				SetTarget( m_hMyBugHole );
				AI_NavGoal_t goal( GOALTYPE_TARGETENT, vec3_origin, ACT_RUN );
				if ( GetNavigator()->SetGoal( goal ) )
				{
					TaskComplete();
					return;
				}
			}

			TaskComplete();
		}
		break;

	case TASK_BBUG_GET_PATH_TO_BUGHOLE:
		{
			// Get a path back to my bughole
			// If we have no squad, or we couldn't get a path to our squadmate, look for a bughole
			if ( m_hMyBugHole )
			{
				SetTarget( m_hMyBugHole );
				AI_NavGoal_t goal( GOALTYPE_TARGETENT, vec3_origin, ACT_RUN );
				if ( GetNavigator()->SetGoal( goal ) )
				{
					TaskComplete();
					return;
				}
			}

			TaskFail( "Couldn't get to bughole." );
		}
		break;

	case TASK_BBUG_HOLE_REMOVE:
		{
			TaskComplete();

			// Crawl inside the bughole and remove myself
			AddEffects( EF_NODRAW );
			AddSolidFlags( FSOLID_NOT_SOLID );
			Event_Killed( CTakeDamageInfo( this, this, 200, DMG_CRUSH ) );

			// Tell the bughole
			if ( m_hMyBugHole )
			{
				m_hMyBugHole->BugReturned();
			}
		}
		break;

	case TASK_BBUG_GET_PATH_TO_DAWDLE:
		{
			// Get a dawdle point ahead of us
			Vector vecForward, vecTarget;
			AngleVectors( GetAbsAngles(), &vecForward );
			VectorMA( GetAbsOrigin(), random->RandomFloat( DAWDLE_MIN_DIST, DAWDLE_MAX_DIST ), vecForward, vecTarget );

			// See how far we could move ahead
			trace_t tr;
			UTIL_TraceEntity( this, GetAbsOrigin(), vecTarget, MASK_SOLID, &tr);
			float flDistance = tr.fraction * (vecTarget - GetAbsOrigin()).Length();
			if ( flDistance >= DAWDLE_MIN_DIST )
			{
				AI_NavGoal_t goal( tr.endpos );
				GetNavigator()->SetGoal( goal );
			}

			TaskComplete();
		}
		break;

	case TASK_BBUG_FACE_DAWDLE:
		{
			// Turn a random amount to the right
			float flYaw = GetMotor()->GetIdealYaw();
			flYaw = flYaw + random->RandomFloat( 45, 135 );
			GetMotor()->SetIdealYaw( UTIL_AngleMod(flYaw) );
			SetTurnActivity();
			break;
		}
		break;

	default:
		BaseClass::StartTask( pTask );
		break;
	}
}
Esempio n. 26
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pTask - 
//-----------------------------------------------------------------------------
void CNPC_Crow::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
		//
		// This task enables us to build a path that requires flight.
		//
//		case TASK_CROW_PREPARE_TO_FLY:
//		{
//			SetFlyingState( FlyState_Flying );
//			TaskComplete();
//			break;
//		}

		case TASK_CROW_TAKEOFF:
		{
			if ( random->RandomInt( 1, 4 ) == 1 )
			{
				AlertSound();
			}

			FlapSound();

			SetIdealActivity( ( Activity )ACT_CROW_TAKEOFF );
			break;
		}

		case TASK_CROW_PICK_EVADE_GOAL:
		{
			if ( GetEnemy() != NULL )
			{
				//
				// Get our enemy's position in x/y.
				//
				Vector vecEnemyOrigin = GetEnemy()->GetAbsOrigin();
				vecEnemyOrigin.z = GetAbsOrigin().z;

				//
				// Pick a hop goal a random distance along a vector away from our enemy.
				//
				m_vSavePosition = GetAbsOrigin() - vecEnemyOrigin;
				VectorNormalize( m_vSavePosition );
				m_vSavePosition = GetAbsOrigin() + m_vSavePosition * ( 32 + random->RandomInt( 0, 32 ) );

				GetMotor()->SetIdealYawToTarget( m_vSavePosition );
				TaskComplete();
			}
			else
			{
				TaskFail( "No enemy" );
			}
			break;
		}

		case TASK_CROW_FALL_TO_GROUND:
		{
			SetFlyingState( FlyState_Falling );
			break;
		}

		case TASK_FIND_HINTNODE:
		{
			if ( GetGoalEnt() )
			{
				TaskComplete();
				return;
			}
			// Overloaded because we search over a greater distance.
			if ( !GetHintNode() )
			{
				SetHintNode(CAI_HintManager::FindHint( this, HINT_CROW_FLYTO_POINT, bits_HINT_NODE_NEAREST | bits_HINT_NODE_USE_GROUP, 10000 ));
			}

			if ( GetHintNode() )
			{
				TaskComplete();
			}
			else
			{
				TaskFail( FAIL_NO_HINT_NODE );
			}
			break;
		}

		case TASK_GET_PATH_TO_HINTNODE:
		{
			//How did this happen?!
			if ( GetGoalEnt() == this )
			{
				SetGoalEnt( NULL );
			}

			if ( GetGoalEnt() )
			{
				SetFlyingState( FlyState_Flying );
				StartTargetHandling( GetGoalEnt() );
			
				m_bReachedMoveGoal = false;
				TaskComplete();
				SetHintNode( NULL );
				return;
			}

			if ( GetHintNode() )
			{
				Vector vHintPos;
				GetHintNode()->GetPosition(this, &vHintPos);
		
				SetNavType( NAV_FLY );
				CapabilitiesAdd( bits_CAP_MOVE_FLY );
				if ( !GetNavigator()->SetGoal( vHintPos ) )
					SetHintNode(NULL);
				CapabilitiesRemove( bits_CAP_MOVE_FLY );
			}

			if ( GetHintNode() )
			{
				m_bReachedMoveGoal = false;
				TaskComplete();
			}
			else
			{
				TaskFail( FAIL_NO_ROUTE );
			}
			break;
		}

		//
		// We have failed to fly normally. Pick a random "up" direction and fly that way.
		//
		case TASK_CROW_FLY:
		{
			float flYaw = UTIL_AngleMod( random->RandomInt( -180, 180 ) );

			Vector vecNewVelocity( cos( DEG2RAD( flYaw ) ), sin( DEG2RAD( flYaw ) ), random->RandomFloat( 0.1f, 0.5f ) );
			vecNewVelocity *= CROW_AIRSPEED;
			SetAbsVelocity( vecNewVelocity );

			SetIdealActivity( ACT_FLY );

			m_bSoar = false;
			m_flSoarTime = gpGlobals->curtime + random->RandomFloat( 2, 5 );

			break;
		}

		case TASK_CROW_PICK_RANDOM_GOAL:
		{
			m_vSavePosition = GetLocalOrigin() + Vector( random->RandomFloat( -48.0f, 48.0f ), random->RandomFloat( -48.0f, 48.0f ), 0 );
			TaskComplete();
			break;
		}

		case TASK_CROW_HOP:
		{
			SetIdealActivity( ACT_HOP );
			m_flHopStartZ = GetLocalOrigin().z;
			break;
		}

		case TASK_CROW_WAIT_FOR_BARNACLE_KILL:
		{
			break;
		}

		default:
		{
			BaseClass::StartTask( pTask );
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *pTask - 
//-----------------------------------------------------------------------------
void CAI_PolicingBehavior::StartTask( const Task_t *pTask )
{
	switch (pTask->iTask)
	{
	case TASK_POLICE_GET_PATH_TO_HARASS_GOAL:
		{
			Vector	harassDir = ( m_hPoliceGoal->GetTarget()->WorldSpaceCenter() - WorldSpaceCenter() );
			float	flDist = VectorNormalize( harassDir );

			// See if we're already close enough
			if ( flDist < pTask->flTaskData )
			{
				TaskComplete();
				break;
			}

			float	flInter1, flInter2;
			Vector	harassPos = GetAbsOrigin() + ( harassDir * ( flDist - pTask->flTaskData ) );

			// Find a point on our policing radius to stand on
			if ( IntersectInfiniteRayWithSphere( GetAbsOrigin(), harassDir, m_hPoliceGoal->GetAbsOrigin(), m_hPoliceGoal->GetRadius(), &flInter1, &flInter2 ) )
			{
				Vector vPos = m_hPoliceGoal->GetAbsOrigin() + harassDir * ( MAX( flInter1, flInter2 ) );

				// See how far away the default one is
				float testDist = UTIL_DistApprox2D( m_hPoliceGoal->GetAbsOrigin(), harassPos );
				
				// If our other goal is closer, choose it
				if ( testDist > UTIL_DistApprox2D( m_hPoliceGoal->GetAbsOrigin(), vPos ) )
				{
					harassPos = vPos;
				}
			}

			if ( GetNavigator()->SetGoal( harassPos, (int)pTask->flTaskData ) )
			{
				GetNavigator()->SetMovementActivity( (Activity) ACT_WALK_ANGRY );
				GetNavigator()->SetArrivalDirection( m_hPoliceGoal->GetTarget() );
				TaskComplete();
			}
			else
			{
				TaskFail( FAIL_NO_ROUTE );
			}
		}
		break;
	
	case TASK_POLICE_GET_PATH_TO_POLICE_GOAL:
		{
			if ( GetNavigator()->SetGoal( m_hPoliceGoal->GetAbsOrigin(), (int)pTask->flTaskData ) )
			{
				GetNavigator()->SetArrivalDirection( m_hPoliceGoal->GetAbsAngles() );
				TaskComplete();
			}
			else
			{
				TaskFail( FAIL_NO_ROUTE );
			}
		}
		break;

	case TASK_POLICE_ANNOUNCE_HARASS:
		{
			AnnouncePolicing();

			// Randomly say this again in the future
			m_flNextHarassTime = gpGlobals->curtime + random->RandomInt( 4, 6 );

			// Scatter rubber-neckers
			CSoundEnt::InsertSound( SOUND_MOVE_AWAY, GetAbsOrigin(), 256, 2.0f, GetOuter() );
		}
		TaskComplete();
		break;

	case TASK_POLICE_FACE_ALONG_GOAL:
		{
			// We may have lost our police goal in the 2 seconds we wait before this task
			if ( m_hPoliceGoal )
			{
				GetMotor()->SetIdealYaw( m_hPoliceGoal->GetAbsAngles().y );
				GetOuter()->SetTurnActivity(); 
			}
		}
		break;

	default:
		BaseClass::StartTask( pTask );
		break;
	}
}
Esempio n. 28
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pTask - 
//-----------------------------------------------------------------------------
void CNPC_Crow::RunTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
		case TASK_CROW_TAKEOFF:
		{
			if ( GetNavigator()->IsGoalActive() )
			{
				GetMotor()->SetIdealYawToTargetAndUpdate( GetAbsOrigin() + GetNavigator()->GetCurWaypointPos(), AI_KEEP_YAW_SPEED );
			}
			else
				TaskFail( FAIL_NO_ROUTE );

			if ( IsActivityFinished() )
			{
				TaskComplete();
				SetIdealActivity( ACT_FLY );

				m_bSoar = false;
				m_flSoarTime = gpGlobals->curtime + random->RandomFloat( 2, 5 );
			}
			
			break;
		}

		case TASK_CROW_HOP:
		{
			if ( IsActivityFinished() )
			{
				TaskComplete();
				SetIdealActivity( ACT_IDLE );
			}

			if ( ( GetAbsOrigin().z < m_flHopStartZ ) && ( !( GetFlags() & FL_ONGROUND ) ) )
			{
				//
				// We've hopped off of something! See if we're going to fall very far.
				//
				trace_t tr;
				AI_TraceLine( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, -32 ), MASK_SOLID, this, HL2COLLISION_GROUP_CROW, &tr );
				if ( tr.fraction == 1.0f )
				{
					//
					// We're falling! Better fly away. SelectSchedule will check ONGROUND and do the right thing.
					//
					TaskComplete();
				}
				else
				{
					//
					// We'll be okay. Don't check again unless what we're hopping onto moves
					// out from under us.
					//
					m_flHopStartZ = GetAbsOrigin().z - ( 32 * tr.fraction );
				}
			}

			break;
		}

		//
		// Face the direction we are flying.
		//
		case TASK_CROW_FLY:
		{
			GetMotor()->SetIdealYawToTargetAndUpdate( GetAbsOrigin() + GetAbsVelocity(), AI_KEEP_YAW_SPEED );

			break;
		}

		case TASK_CROW_FALL_TO_GROUND:
		{
			if ( GetFlags() & FL_ONGROUND )
			{
				SetFlyingState( FlyState_Walking );
				TaskComplete();
			}
			break;
		}

		case TASK_CROW_WAIT_FOR_BARNACLE_KILL:
		{
			if ( m_flNextFlinchTime < gpGlobals->curtime )
			{
				m_flNextFlinchTime = gpGlobals->curtime + random->RandomFloat( 0.5f, 2.0f );
				// dvs: TODO: squirm
				// dvs: TODO: spawn feathers
				EmitSound( "NPC_Crow.Squawk" );
			}
			break;
		}

		default:
		{
			CAI_BaseNPC::RunTask( pTask );
		}
	}
}
Esempio n. 29
0
//-----------------------------------------------------------------------------
// Purpose: Determines the pose parameters for the bending of the body and tail speed
// Input  : moveRel - the dot products for the deviation off of each direction (f,r,u)
//			speed - speed of the fish
//-----------------------------------------------------------------------------
void CNPC_Ichthyosaur::SetPoses( Vector moveRel, float speed )
{
	float	movePerc, moveBase;

	//Find out how fast we're moving in our animations boundaries
	if ( GetIdealActivity() == ACT_WALK )
	{
		moveBase = 0.5f;
		movePerc = moveBase * ( speed / ICH_SWIM_SPEED_WALK );
	}
	else
	{
		moveBase = 1.0f;
		movePerc = moveBase * ( speed / ICH_SWIM_SPEED_RUN );
	}
	
	Vector	tailPosition;
	float	flSwimSpeed = movePerc;

	//Forward deviation
	if ( moveRel.x > 0 )
	{
		flSwimSpeed *= moveBase + (( moveRel.x / m_vecAccelerationMax.x )*moveBase);
	}
	else if ( moveRel.x < 0 )
	{
		flSwimSpeed *= moveBase - (( moveRel.x / m_vecAccelerationMin.x )*moveBase);
	}

	//Vertical deviation
	if ( moveRel.z > 0 )
	{
		tailPosition[PITCH]	= -90.0f * ( moveRel.z / m_vecAccelerationMax.z );
	}
	else if ( moveRel.z < 0 )
	{
		tailPosition[PITCH]	= 90.0f * ( moveRel.z / m_vecAccelerationMin.z );
	}
	else
	{
		tailPosition[PITCH]	= 0.0f;
	}

	//Lateral deviation
	if ( moveRel.y > 0 )
	{
		tailPosition[ROLL]	= 25 * moveRel.y / m_vecAccelerationMax.y;
		tailPosition[YAW]	= -1.0f * moveRel.y / m_vecAccelerationMax.y;
	}
	else if ( moveRel.y < 0 )
	{
		tailPosition[ROLL]	= -25 * moveRel.y / m_vecAccelerationMin.y;
		tailPosition[YAW]	= moveRel.y / m_vecAccelerationMin.y;
	}
	else
	{
		tailPosition[ROLL]	= 0.0f;
		tailPosition[YAW]	= 0.0f;
	}
	
	//Clamp
	flSwimSpeed			= clamp( flSwimSpeed, 0.25f, 1.0f );
	tailPosition[YAW]	= clamp( tailPosition[YAW], -90.0f, 90.0f );
	tailPosition[PITCH]	= clamp( tailPosition[PITCH], -90.0f, 90.0f );

	//Blend
	m_flTailYaw		= ( m_flTailYaw * 0.8f ) + ( tailPosition[YAW] * 0.2f );
	m_flTailPitch	= ( m_flTailPitch * 0.8f ) + ( tailPosition[PITCH] * 0.2f );
	m_flSwimSpeed	= ( m_flSwimSpeed * 0.8f ) + ( flSwimSpeed * 0.2f );

	//Pose the body
	SetPoseParameter( 0, m_flSwimSpeed );
	SetPoseParameter( 1, m_flTailYaw );
	SetPoseParameter( 2, m_flTailPitch );
	
	//FIXME: Until the sequence info is reset properly after SetPoseParameter
	if ( ( GetActivity() == ACT_RUN ) || ( GetActivity() == ACT_WALK ) )
	{
		ResetSequenceInfo();
	}

	//Face our current velocity
	GetMotor()->SetIdealYawAndUpdate( UTIL_AngleMod( CalcIdealYaw( GetAbsOrigin() + GetAbsVelocity() ) ), AI_KEEP_YAW_SPEED );

	float	pitch = 0.0f;

	if ( speed != 0.0f )
	{
		pitch = -RAD2DEG( asin( GetAbsVelocity().z / speed ) );
	}

	//FIXME: Framerate dependant
	QAngle angles = GetLocalAngles();

	angles.x = (angles.x * 0.8f) + (pitch * 0.2f);
	angles.z = (angles.z * 0.9f) + (tailPosition[ROLL] * 0.1f);

	SetLocalAngles( angles );
}
Esempio n. 30
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CAI_FuncTankBehavior::StartTask( const Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_FUNCTANK_ANNOUNCE_SCAN:
		{
			if ( random->RandomInt( 0, 3 ) == 0 )
			{
				GetOuter()->SpeakSentence( FUNCTANK_SENTENCE_SCAN_FOR_ENEMIES );
			}
			TaskComplete();
		}
		break;

	case TASK_GET_PATH_TO_FUNCTANK:
		{
			if ( !m_hFuncTank )
			{
				TaskFail( FAIL_NO_TARGET  );
				return;
			}

			Vector vecManPos;
			m_hFuncTank->NPC_FindManPoint( vecManPos );
			AI_NavGoal_t goal( vecManPos );
			goal.pTarget = m_hFuncTank;
			if ( GetNavigator()->SetGoal( goal ) )
			{
				GetNavigator()->SetArrivalDirection( m_hFuncTank->GetAbsAngles() );
				TaskComplete();
			}
			else
			{
				TaskFail("NO PATH");

				// Don't try and use me again for a while
				SetBusy( gpGlobals->curtime + AI_FUNCTANK_BEHAVIOR_BUSYTIME );
			}
			break;
		}		
	case TASK_FACE_FUNCTANK:
		{
			if ( !m_hFuncTank )
			{
				TaskFail( FAIL_NO_TARGET );
				return;
			}
			
			// Ensure we've reached the func_tank
			Vector vecManPos;
			m_hFuncTank->NPC_FindManPoint( vecManPos );

			// More leniency in Z.
			Vector vecDelta = (vecManPos - GetAbsOrigin());
			if ( fabs(vecDelta.x) > 16 || fabs(vecDelta.y) > 16 || fabs(vecDelta.z) > 48 )
			{
				TaskFail( "Not correctly on func_tank man point" );
				m_hFuncTank->NPC_InterruptRoute();
				return;
			}

			GetMotor()->SetIdealYawToTarget( m_hFuncTank->GetAbsOrigin() );
			GetOuter()->SetTurnActivity(); 
			break;
		}

	case TASK_HOLSTER_WEAPON:
		{
			if ( !m_hFuncTank )
			{
				TaskFail( FAIL_NO_TARGET );
				return;
			}

			if ( GetOuter()->IsWeaponHolstered() || !GetOuter()->CanHolsterWeapon() )
			{
				GetOuter()->SpeakSentence( FUNCTANK_SENTENCE_JUST_MOUNTED );

				// We are at the correct position and facing for the func_tank, mount it.
				m_hFuncTank->StartControl( GetOuter() );
				GetOuter()->ClearEnemyMemory();
				m_bMounted = true;
				TaskComplete();

				GetOuter()->SetIdealActivity( ACT_IDLE_MANNEDGUN );
			}
			else
			{
				GetOuter()->SetDesiredWeaponState( DESIREDWEAPONSTATE_HOLSTERED );
			}
			break;
		}

	case TASK_FIRE_FUNCTANK:
		{
			if ( !m_hFuncTank )
			{
				TaskFail( FAIL_NO_TARGET );
				return;
			}
			GetOuter()->m_flWaitFinished = gpGlobals->curtime + FUNCTANK_FIRE_TIME;
			break;
		}
	case TASK_SCAN_LEFT_FUNCTANK:
		{
			if ( !m_hFuncTank )
			{
				TaskFail( FAIL_NO_TARGET );
				return;
			}

			GetMotor()->SetIdealYawToTarget( m_hFuncTank->GetAbsOrigin() );

			float flCenterYaw = m_hFuncTank->YawCenterWorld();
			float flYawRange = m_hFuncTank->YawRange();
			float flScanAmount = random->RandomFloat( 0, flYawRange );
			QAngle vecTargetAngles( 0, UTIL_AngleMod( flCenterYaw + flScanAmount ), 0 );

			/*
			float flCenterPitch = m_hFuncTank->YawCenterWorld();
			float flPitchRange = m_hFuncTank->PitchRange();
			float flPitch = random->RandomFloat( -flPitchRange, flPitchRange );
			QAngle vecTargetAngles( flCenterPitch + flPitch, UTIL_AngleMod( flCenterYaw + flScanAmount ), 0 );
			*/

			Vector vecTargetForward;
			AngleVectors( vecTargetAngles, &vecTargetForward );
			Vector vecTarget = GetOuter()->EyePosition() + (vecTargetForward * 256);
			GetOuter()->AddLookTarget( vecTarget, 1.0, 2.0, 0.2 );

			m_hFuncTank->NPC_SetIdleAngle( vecTarget );

			break;
		}
	case TASK_SCAN_RIGHT_FUNCTANK:
		{
			if ( !m_hFuncTank )
			{
				TaskFail( FAIL_NO_TARGET );
				return;
			}

			GetMotor()->SetIdealYawToTarget( m_hFuncTank->GetAbsOrigin() );

			float flCenterYaw = m_hFuncTank->YawCenterWorld();
			float flYawRange = m_hFuncTank->YawRange();
			float flScanAmount = random->RandomFloat( 0, flYawRange );
			QAngle vecTargetAngles( 0, UTIL_AngleMod( flCenterYaw - flScanAmount ), 0 );

			/*
			float flCenterPitch = m_hFuncTank->YawCenterWorld();
			float flPitchRange = m_hFuncTank->PitchRange();
			float flPitch = random->RandomFloat( -flPitchRange, flPitchRange );
			QAngle vecTargetAngles( flCenterPitch + flPitch, UTIL_AngleMod( flCenterYaw - flScanAmount ), 0 );
			*/

			Vector vecTargetForward;
			AngleVectors( vecTargetAngles, &vecTargetForward );
			Vector vecTarget = GetOuter()->EyePosition() + (vecTargetForward * 256);
			GetOuter()->AddLookTarget( vecTarget, 1.0, 2.0, 0.2 );

			m_hFuncTank->NPC_SetIdleAngle( vecTarget );

			break;
		}
	case TASK_FORGET_ABOUT_FUNCTANK:
		{
			if ( !m_hFuncTank )
			{
				TaskFail( FAIL_NO_TARGET );
				return;
			}
			break;
		}
	default:
		{
			BaseClass::StartTask( pTask );
			break;
		}
	}
}