bool CAI_LeadBehavior::CanSelectSchedule()
{
 	if ( !AI_GetSinglePlayer() || AI_GetSinglePlayer()->IsDead() )
		return false;

	bool fAttacked = ( HasCondition( COND_LIGHT_DAMAGE ) || HasCondition( COND_HEAVY_DAMAGE ) );
	bool fNonCombat = ( GetNpcState() == NPC_STATE_IDLE || GetNpcState() == NPC_STATE_ALERT );
	
	return ( !fAttacked && (fNonCombat || m_args.bLeadDuringCombat) && HasGoal() );
}
void CParticleSystemQuery::GetLocalPlayerEyeVectors( Vector *pForward, Vector *pRight, Vector *pUp )
{
#ifdef CLIENT_DLL
//	HACK_GETLOCALPLAYER_GUARD( "CParticleSystemQuery::GetLocalPlayerPos" );
	int slot = GET_ACTIVE_SPLITSCREEN_SLOT();
	ACTIVE_SPLITSCREEN_PLAYER_GUARD( slot );
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
	{
		*pForward = vec3_origin;
		*pRight = vec3_origin;
		*pUp = vec3_origin;
		return;
	}
	pPlayer->EyeVectors( pForward, pRight, pUp );
#else
	CBasePlayer *pPlayer = AI_GetSinglePlayer();	
	if ( !pPlayer )
	{
		*pForward = vec3_origin;
		*pRight = vec3_origin;
		*pUp = vec3_origin;
		return;
	}
	pPlayer->EyeVectors( pForward, pRight, pUp );
#endif
}
CBaseEntity *CAI_StandoffBehavior::GetPlayerLeader()
{
	CBaseEntity *pPlayer = AI_GetSinglePlayer();
	if ( pPlayer && GetOuter()->IRelationType( pPlayer ) == D_LI )
		return pPlayer;
	return NULL;
}
Ejemplo n.º 4
0
//------------------------------------------------------------------------
// Purpose: 
// Input  : &inputdata - 
//-----------------------------------------------------------------------------
void CScriptIntro::InputSetFOVBlendTime( inputdata_t &inputdata )
{
	// Cache our FOV starting point before we update our data here
	if ( m_flNextFOVBlendTime >= gpGlobals->curtime )
	{
		// We're already in a blend, so capture where we are at this point in time
		m_iStartFOV = ScriptInfo_CalculateFOV( m_flFOVBlendStartTime, m_flNextFOVBlendTime, m_iStartFOV, m_iNextFOV, m_bAlternateFOV );
	}
	else
	{
		// If we weren't blending, then we need to construct a proper starting point from scratch
		CBasePlayer *pPlayer = AI_GetSinglePlayer();
		if ( pPlayer )
		{
			m_iStartFOV = ( m_iFOV ) ? m_iFOV : pPlayer->GetFOV();
		}
		else
		{
			m_iStartFOV = m_iFOV;
		}
	}

	m_flNextFOVBlendTime = gpGlobals->curtime + inputdata.value.Float();
	m_flFOVBlendStartTime = gpGlobals->curtime;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &inputdata - 
//-----------------------------------------------------------------------------
void CPropVehicleChoreoGeneric::InputEnterVehicleImmediate( inputdata_t &inputdata )
{
	if ( m_bEnterAnimOn )
		return;

	// Try the activator first & use them if they are a player.
	CBasePlayer *pPlayer = ToBasePlayer( inputdata.pActivator );
	if ( pPlayer == NULL )
	{
		// Activator was not a player, just grab the singleplayer player.
		pPlayer = AI_GetSinglePlayer();
		if ( pPlayer == NULL )
			return;
	}

	if ( pPlayer->IsInAVehicle() )
	{
		// Force the player out of whatever vehicle they are in.
		pPlayer->LeaveVehicle();
	}
	
	// Force us to drop anything we're holding
	pPlayer->ForceDropOfCarriedPhysObjects();

	pPlayer->GetInVehicle( GetServerVehicle(), VEHICLE_ROLE_DRIVER );
}
//-----------------------------------------------------------------------------
// Purpose: Force the player to enter the vehicle.
//-----------------------------------------------------------------------------
void CPropVehicleChoreoGeneric::InputEnterVehicle( inputdata_t &inputdata )
{
	if ( m_bEnterAnimOn )
		return;

	// Try the activator first & use them if they are a player.
	CBasePlayer *pPlayer = ToBasePlayer( inputdata.pActivator );
	if ( pPlayer == NULL )
	{
		// Activator was not a player, just grab the single-player player.
		pPlayer = AI_GetSinglePlayer();
		if ( pPlayer == NULL )
			return;
	}

	// Force us to drop anything we're holding
	pPlayer->ForceDropOfCarriedPhysObjects();

	// FIXME: I hate code like this. I should really add a parameter to HandlePassengerEntry
	//		  to allow entry into locked vehicles
	bool bWasLocked = m_bLocked;
	m_bLocked = false;
	GetServerVehicle()->HandlePassengerEntry( pPlayer, true );
	m_bLocked = bWasLocked;
}
void CAI_LeadBehavior::BeginScheduleSelection()
{
	SetTarget( AI_GetSinglePlayer() );
	CAI_Expresser *pExpresser = GetOuter()->GetExpresser();
	if ( pExpresser )
		pExpresser->ClearSpokeConcept( TLK_LEAD_ARRIVAL );
}
Ejemplo n.º 8
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CAI_Hint *CAI_FearBehavior::FindFearWithdrawalDest()
{
	CAI_Hint *pHint;
	CHintCriteria hintCriteria;
	CAI_BaseNPC *pOuter = GetOuter();

	Assert(pOuter != NULL);

	hintCriteria.AddHintType( HINT_PLAYER_ALLY_FEAR_DEST );
	hintCriteria.SetFlag( bits_HINT_NODE_VISIBLE_TO_PLAYER | bits_HINT_NOT_CLOSE_TO_ENEMY /*| bits_HINT_NODE_IN_VIEWCONE | bits_HINT_NPC_IN_NODE_FOV*/ );
	hintCriteria.AddIncludePosition( AI_GetSinglePlayer()->GetAbsOrigin(), ( ai_fear_player_dist.GetFloat() ) );

	pHint = CAI_HintManager::FindHint( pOuter, hintCriteria );

	if( pHint )
	{
		// Reserve this node while I try to get to it. When I get there I will lock it.
		// Otherwise, if I fail to get there, the node will come available again soon.
		pHint->DisableForSeconds( 4.0f );
	}
#if 0
	else
	{
		Msg("DID NOT FIND HINT\n");
		NDebugOverlay::Cross3D( GetOuter()->WorldSpaceCenter(), 32, 255, 255, 0, false, 10.0f );
	}
#endif

	return pHint;
}
Ejemplo n.º 9
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponStriderBuster::Detonate( void )
{
	CBaseEntity *pVictim = GetOwnerEntity();
	if ( !m_bDud && pVictim )
	{
		// Kill the strider (with magic effect)
		CBasePlayer *pPlayer = AI_GetSinglePlayer();
		CTakeDamageInfo info( pPlayer, this, RandomVector( -100.0f, 100.0f ), GetAbsOrigin(), pVictim->GetHealth(), DMG_GENERIC );
		pVictim->TakeDamage( info );

		gamestats->Event_WeaponHit( ToBasePlayer( pPlayer ), true, GetClassname(), info );

		// Tracker 62293:  There's a bug where the inflictor/attacker are reversed when calling TakeDamage above so the player never gets
		//  credit for the strider buster kills.  The code has a bunch of assumptions lower level, so it's safer to just fix it here by 
		//  crediting a kill to the player directly.
		gamestats->Event_PlayerKilledOther( pPlayer, pVictim, info );
	}

	m_OnDetonate.FireOutput( this, this );

	// Explode
	if ( !m_bDud )
	{
		CreateDestroyedEffect();
		EmitSound( "Weapon_StriderBuster.Detonate" );
	}
	else
	{
		DispatchParticleEffect( "striderbuster_explode_dummy_core", GetAbsOrigin(), GetAbsAngles() );
		EmitSound( "Weapon_StriderBuster.Dud_Detonate" );
	}

	// Go to bits!
	Shatter( pVictim );
}
Ejemplo n.º 10
0
void CNPC_Zombine::GatherGrenadeConditions( void )
{
	if ( m_iGrenadeCount <= 0 )
		return;

	if ( g_flZombineGrenadeTimes > gpGlobals->curtime )
		return;

	if ( m_flGrenadePullTime > gpGlobals->curtime )
		return;

	if ( m_flSuperFastAttackTime >= gpGlobals->curtime )
		return;
	
	if ( HasGrenade() )
		return;

	if ( GetEnemy() == NULL )
		return;

	if ( FVisible( GetEnemy() ) == false )
		return;

	if ( IsSprinting() )
		return;

	if ( IsOnFire() )
		return;
	
	if ( IsRunningDynamicInteraction() == true )
		return;

	if ( m_ActBusyBehavior.IsActive() )
		return;

	CBasePlayer *pPlayer = AI_GetSinglePlayer();

	if ( pPlayer && pPlayer->FVisible( this ) )
	{
		float flLengthToPlayer = (pPlayer->GetAbsOrigin() - GetAbsOrigin()).Length();
		float flLengthToEnemy = flLengthToPlayer;

		if ( pPlayer != GetEnemy() )
		{
			flLengthToEnemy = ( GetEnemy()->GetAbsOrigin() - GetAbsOrigin()).Length();
		}

		if ( flLengthToPlayer <= GRENADE_PULL_MAX_DISTANCE && flLengthToEnemy <= GRENADE_PULL_MAX_DISTANCE )
		{
			float flPullChance = 1.0f - ( flLengthToEnemy / GRENADE_PULL_MAX_DISTANCE );
			m_flGrenadePullTime = gpGlobals->curtime + 0.5f;

			if ( flPullChance >= random->RandomFloat( 0.0f, 1.0f ) )
			{
				g_flZombineGrenadeTimes = gpGlobals->curtime + 10.0f;
				SetCondition( COND_ZOMBINE_GRENADE );
			}
		}
	}
}
Ejemplo n.º 11
0
bool CNPC_Zombine::AllowedToSprint( void )
{
	if ( IsOnFire() )
		return false;
	
	//If you're sprinting then there's no reason to sprint again.
	if ( IsSprinting() )
		return false;

	int iChance = SPRINT_CHANCE_VALUE;

	CHL2_Player *pPlayer = dynamic_cast <CHL2_Player*> ( AI_GetSinglePlayer() );

	if ( pPlayer )
	{
		if ( HL2GameRules()->IsAlyxInDarknessMode() && pPlayer->FlashlightIsOn() == false )
		{
			iChance = SPRINT_CHANCE_VALUE_DARKNESS;
		}

		//Bigger chance of this happening if the player is not looking at the zombie
		if ( pPlayer->FInViewCone( this ) == false )
		{
			iChance *= 2;
		}
	}

	if ( HasGrenade() ) 
	{
		iChance *= 4;
	}

	//Below 25% health they'll always sprint
	if ( ( GetHealth() > GetMaxHealth() * 0.5f ) )
	{
		if ( IsStrategySlotRangeOccupied( SQUAD_SLOT_ZOMBINE_SPRINT1, SQUAD_SLOT_ZOMBINE_SPRINT2 ) == true )
			return false;
		
		if ( random->RandomInt( 0, 100 ) > iChance )
			return false;
		
		if ( m_flSprintRestTime > gpGlobals->curtime )
			return false;
	}

	float flLength = ( GetEnemy()->WorldSpaceCenter() - WorldSpaceCenter() ).Length();

	if ( flLength > MAX_SPRINT_DISTANCE )
		return false;

	return true;
}
Ejemplo n.º 12
0
//-----------------------------------------------------------------------------
// Purpose: Blend the parameters to the specified value
//-----------------------------------------------------------------------------
void CEnvDOFController::UpdateParamBlend( void )
{ 
	// Update our focal target if we have one
	if ( m_hFocusTarget )
	{
		CBasePlayer *pPlayer = AI_GetSinglePlayer();
		float flDistToFocus = ( m_hFocusTarget->GetAbsOrigin() - pPlayer->GetAbsOrigin() ).Length();
		m_flFarFocusDepth.GetForModify() = flDistToFocus + m_flFocusTargetRange;
		m_flFarBlurDepth.GetForModify() = m_flFarFocusDepth + BLUR_DEPTH;
	}

	SetThink( &CEnvDOFController::UpdateParamBlend );
	SetNextThink( gpGlobals->curtime + 0.1f );
}
Ejemplo n.º 13
0
void CNPC_Dog::SetupThrowTarget( void )
{
	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
		
	}

	SetTarget( m_hThrowTarget );
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAI_PassengerBehaviorZombie::GatherConditions( void )
{
	BaseClass::GatherConditions();

	// Always clear the base conditions
	ClearCondition( COND_CAN_MELEE_ATTACK1 );

	// Behavior when outside the vehicle
	if ( GetPassengerState() == PASSENGER_STATE_OUTSIDE )
	{
		if ( CanBeOnEnemyVehicle() && CanJumpToAttachToVehicle() )
		{
			SetCondition( COND_CAN_RANGE_ATTACK1 );
		}
		
		// Determine if we can latch on to the vehicle (out of sight)
		ClearCondition( COND_PASSENGER_ZOMBIE_CAN_ATTACH_TO_VEHICLE );
		CBasePlayer *pPlayer = AI_GetSinglePlayer();
		
		if ( pPlayer != NULL && 
			 GetOuter()->GetEnemy() == pPlayer && 
			 pPlayer->GetVehicleEntity() == m_hVehicle )
		{
			// Can't be visible to the player and must be close enough
			bool bNotVisibleToPlayer = ( pPlayer->FInViewCone( GetOuter() ) == false );
			float flDistSqr = ( pPlayer->GetAbsOrigin() - GetOuter()->GetAbsOrigin() ).LengthSqr();
			bool bInRange = ( flDistSqr < Square(250.0f) );
			if ( bNotVisibleToPlayer && bInRange )
			{
				// We can latch on and "enter" the vehicle
				SetCondition( COND_PASSENGER_ZOMBIE_CAN_ATTACH_TO_VEHICLE );
			}
			else if ( bNotVisibleToPlayer == false && flDistSqr < Square(128.0f) )
			{
				// Otherwise just hit the vehicle in anger
				SetCondition( COND_CAN_MELEE_ATTACK1 );
			}
		}
	}

	// Behavior when on the car
	if ( GetPassengerState() == PASSENGER_STATE_INSIDE )
	{
		// Check for melee attack
		if ( GetOuter()->GetNextAttack() < gpGlobals->curtime )
		{
			SetCondition( COND_CAN_MELEE_ATTACK1 );
		}
	}
}
Ejemplo n.º 15
0
Vector CParticleSystemQuery::GetLocalPlayerPos( void )
{
#ifdef CLIENT_DLL
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return vec3_origin;
	return pPlayer->WorldSpaceCenter();
#else
	CBasePlayer *pPlayer = AI_GetSinglePlayer();	
	if ( !pPlayer )
		return vec3_origin;
	return pPlayer->WorldSpaceCenter();
#endif
}
Ejemplo n.º 16
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAntlionGrub::SetNextThinkByDistance( void )
{
	CBasePlayer *pPlayer = AI_GetSinglePlayer();
	if ( pPlayer == NULL )
	{
		SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.5f, 3.0f ) );
		return;
	}

	float flDistToPlayerSqr = ( GetAbsOrigin() - pPlayer->GetAbsOrigin() ).LengthSqr();
	float scale = RemapValClamped( flDistToPlayerSqr, Square( 400 ), Square( 5000 ), 1.0f, 5.0f );
	float time = random->RandomFloat( 1.0f, 3.0f );
	SetNextThink( gpGlobals->curtime + ( time * scale ) );
}
Ejemplo n.º 17
0
Vector CParticleSystemQuery::GetLocalPlayerPos( void )
{
#ifdef CLIENT_DLL
//	HACK_GETLOCALPLAYER_GUARD( "CParticleSystemQuery::GetLocalPlayerPos" );
	int slot = GET_ACTIVE_SPLITSCREEN_SLOT();
	ACTIVE_SPLITSCREEN_PLAYER_GUARD( slot );
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
		return vec3_origin;
	return pPlayer->WorldSpaceCenter();
#else
	CBasePlayer *pPlayer = AI_GetSinglePlayer();	
	if ( !pPlayer )
		return vec3_origin;
	return pPlayer->WorldSpaceCenter();
#endif
}
Ejemplo n.º 18
0
//-----------------------------------------------------------------------------
// Purpose: Find what size of nugget to spawn
//-----------------------------------------------------------------------------
int CAntlionGrub::GetNuggetDenomination( void )
{
	// Find the desired health perc we want to be at
	float flDesiredHealthPerc = DynamicResupply_GetDesiredHealthPercentage();
	
	CBasePlayer *pPlayer = AI_GetSinglePlayer();
	if ( pPlayer == NULL )
		return -1;

	// Get the player's current health percentage
	float flPlayerHealthPerc = (float) pPlayer->GetHealth() / (float) pPlayer->GetMaxHealth();

	// If we're already maxed out, return the small nugget
	if ( flPlayerHealthPerc >= flDesiredHealthPerc )
	{
		return NUGGET_SMALL;
	}

	// Find where we fall in the desired health's range
	float flPercDelta = flPlayerHealthPerc / flDesiredHealthPerc;

	// The larger to discrepancy, the higher the chance to move quickly to close it
	float flSeed = random->RandomFloat( 0.0f, 1.0f );
	float flRandomPerc = Bias( flSeed, (1.0f-flPercDelta) );
	
	int nDenomination;
	if ( flRandomPerc < 0.25f )
	{
		nDenomination = NUGGET_SMALL;
	}
	else if ( flRandomPerc < 0.625f )
	{
		nDenomination = NUGGET_MEDIUM;
	}
	else
	{
		nDenomination = NUGGET_LARGE;
	}

	// Msg("Player: %.02f, Desired: %.02f, Seed: %.02f, Perc: %.02f, Result: %d\n", flPlayerHealthPerc, flDesiredHealthPerc, flSeed, flRandomPerc, nDenomination );

	return nDenomination;
}
Ejemplo n.º 19
0
void CGrenadeSpit::Think( void )
{
	InitHissSound();
	if ( m_pHissSound == NULL )
		return;
	
	// Add a doppler effect to the balls as they travel
#ifdef HL2SB
	CBaseEntity *pPlayer = AI_GetNearestPlayer( GetAbsOrigin() );
#else
	CBaseEntity *pPlayer = AI_GetSinglePlayer();
#endif
	if ( pPlayer != NULL )
	{
		Vector dir;
		VectorSubtract( pPlayer->GetAbsOrigin(), GetAbsOrigin(), dir );
		VectorNormalize(dir);

		float velReceiver = DotProduct( pPlayer->GetAbsVelocity(), dir );
		float velTransmitter = -DotProduct( GetAbsVelocity(), dir );
		
		// speed of sound == 13049in/s
		int iPitch = 100 * ((1 - velReceiver / 13049) / (1 + velTransmitter / 13049));

		// clamp pitch shifts
		if ( iPitch > 250 )
		{
			iPitch = 250;
		}
		if ( iPitch < 50 )
		{
			iPitch = 50;
		}

		// Set the pitch we've calculated
		CSoundEnvelopeController::GetController().SoundChangePitch( m_pHissSound, iPitch, 0.1f );
	}

	// Set us up to think again shortly
	SetNextThink( gpGlobals->curtime + 0.05f );
}
Ejemplo n.º 20
0
//------------------------------------------------------------------------------
bool CNPC_EnemyFinder::ShouldAlwaysThink()
{
	if ( BaseClass::ShouldAlwaysThink() )
		return true;
		
	CBasePlayer *pPlayer = AI_GetSinglePlayer();
	if ( pPlayer && IRelationType( pPlayer ) == D_HT )
	{
		float playerDistSqr = GetAbsOrigin().DistToSqr( pPlayer->GetAbsOrigin() );

		if ( !m_flMaxSearchDist || playerDistSqr <= Square(m_flMaxSearchDist) )
		{
			if ( !FBitSet( m_spawnflags, SF_ENEMY_FINDER_CHECK_VIS) )
				return true;
				
			if ( playerDistSqr <= Square( 50 * 12 ) )
				return true;
		}
	}
	
	return false;
}
Ejemplo n.º 21
0
//-----------------------------------------------------------------------------
// Purpose: Return true if the player is further ahead on the lead route than I am
//-----------------------------------------------------------------------------
bool CAI_LeadBehavior::PlayerIsAheadOfMe( bool bForce )
{
	// Find the nearest point on our route to the player, and see if that's further 
	// ahead of us than our nearest point. 

	// If we're not leading, our route doesn't lead to the goal, so we can't use it.
	// If we just started leading, go ahead and test, and we'll build a temp route.
	if ( !m_bInitialAheadTest && !IsCurSchedule( SCHED_LEAD_PLAYER, false ) && !bForce )
		return false;

	m_bInitialAheadTest = false;

	Vector vecClosestPoint;
	if ( GetClosestPointOnRoute( AI_GetSinglePlayer()->GetAbsOrigin(), &vecClosestPoint ) )
	{
		// If the closest point is not right next to me, then 
		// the player is somewhere ahead of me on the route.
		if ( (vecClosestPoint - GetOuter()->GetAbsOrigin()).LengthSqr() > (32*32) )
			return true;
	}

	return false;
}
Ejemplo n.º 22
0
void CParticleSystemQuery::GetLocalPlayerEyeVectors( Vector *pForward, Vector *pRight, Vector *pUp )
{
#ifdef CLIENT_DLL
	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
	if ( !pPlayer )
	{
		*pForward = vec3_origin;
		*pRight = vec3_origin;
		*pUp = vec3_origin;
		return;
	}
	pPlayer->EyeVectors( pForward, pRight, pUp );
#else
	CBasePlayer *pPlayer = AI_GetSinglePlayer();	
	if ( !pPlayer )
	{
		*pForward = vec3_origin;
		*pRight = vec3_origin;
		*pUp = vec3_origin;
		return;
	}
	pPlayer->EyeVectors( pForward, pRight, pUp );
#endif
}
Ejemplo n.º 23
0
void CNPC_Dog::SetPlayerAvoidState( void )
{
	bool bIntersectingBoneFollowers = false;
	bool bIntersectingNPCBox = false;

	Vector vNothing;

	GetSequenceLinearMotion( GetSequence(), &vNothing );
	bool bIsMoving = ( IsMoving() || ( vNothing != vec3_origin ) );

	//If we are coming out of a script, check if we are stuck inside the player.
	if ( m_bPerformAvoidance || ( ShouldPlayerAvoid() && bIsMoving ) )
	{
		trace_t trace;
		Vector vMins, vMaxs;
		Vector vWorldMins, vWorldMaxs;
		Vector vPlayerMins, vPlayerMaxs;
		physfollower_t *pBone;
		int i;
		
		#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
			CBasePlayer *pLocalPlayer = UTIL_GetNearestPlayer(GetAbsOrigin()); 
		#else
			CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
		#endif //SecobMod__Enable_Fixed_Multiplayer_AI

		if ( pLocalPlayer )
		{
			vWorldMins = WorldAlignMins();
			vWorldMaxs = WorldAlignMaxs();

			vPlayerMins = pLocalPlayer->GetAbsOrigin() + pLocalPlayer->WorldAlignMins();
			vPlayerMaxs = pLocalPlayer->GetAbsOrigin() + pLocalPlayer->WorldAlignMaxs();

			// check if the player intersects the bounds of any of the bone followers
			for ( i = 0; i < m_BoneFollowerManager.GetNumBoneFollowers(); i++ )
			{
				pBone = m_BoneFollowerManager.GetBoneFollower( i );
				if ( pBone && pBone->hFollower )
				{
					pBone->hFollower->CollisionProp()->WorldSpaceSurroundingBounds( &vMins, &vMaxs );
					if ( IsBoxIntersectingBox( vMins, vMaxs, vPlayerMins, vPlayerMaxs ) )
					{
						bIntersectingBoneFollowers = true;
						break;
					}
				}
			}

			bIntersectingNPCBox = IsBoxIntersectingBox( GetAbsOrigin() + vWorldMins, GetAbsOrigin() + vWorldMaxs, vPlayerMins, vPlayerMaxs );

			if ( ai_debug_avoidancebounds.GetBool() )
			{
				int iRed = ( bIntersectingNPCBox == true ) ? 255 : 0;

				NDebugOverlay::Box( GetAbsOrigin(), vWorldMins, vWorldMaxs, iRed, 0, 255, 64, 0.1 );

				// draw the bounds of the bone followers
				for ( i = 0; i < m_BoneFollowerManager.GetNumBoneFollowers(); i++ )
				{
					pBone = m_BoneFollowerManager.GetBoneFollower( i );
					if ( pBone && pBone->hFollower )
					{
						pBone->hFollower->CollisionProp()->WorldSpaceSurroundingBounds( &vMins, &vMaxs );
						iRed = ( IsBoxIntersectingBox( vMins, vMaxs, vPlayerMins, vPlayerMaxs ) ) ? 255 : 0;

						NDebugOverlay::Box( vec3_origin, vMins, vMaxs, iRed, 0, 255, 64, 0.1 );
					}
				}
			}
		}
	}

	m_bPlayerAvoidState = ShouldPlayerAvoid();
	m_bPerformAvoidance = bIntersectingNPCBox || bIntersectingBoneFollowers;

	if ( GetCollisionGroup() == COLLISION_GROUP_NPC || GetCollisionGroup() == COLLISION_GROUP_NPC_ACTOR )
	{
		if ( bIntersectingNPCBox == true )
		{
			SetCollisionGroup( COLLISION_GROUP_NPC_ACTOR );
		}
		else
		{
			SetCollisionGroup( COLLISION_GROUP_NPC );
		}

		if ( bIntersectingBoneFollowers == true )
		{
			MantainBoneFollowerCollisionGroups( COLLISION_GROUP_NPC_ACTOR );
		}
		else
		{
			MantainBoneFollowerCollisionGroups( COLLISION_GROUP_NPC );
		}
	}
}
Ejemplo n.º 24
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 );
	}
}
Ejemplo n.º 25
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CAI_FearBehavior::GatherConditions()
{
	BaseClass::GatherConditions();

	ClearCondition( COND_FEAR_ENEMY_CLOSE );
	ClearCondition( COND_FEAR_ENEMY_TOO_CLOSE );
	if( GetEnemy() )
	{
		float flEnemyDistSqr = GetAbsOrigin().DistToSqr(GetEnemy()->GetAbsOrigin());

		if( flEnemyDistSqr < FEAR_ENEMY_TOLERANCE_TOO_CLOSE_DIST_SQR )
		{
			SetCondition( COND_FEAR_ENEMY_TOO_CLOSE );
			if( IsInASafePlace() )
			{
				SpoilSafePlace();
			}
		}
		else if( flEnemyDistSqr < FEAR_ENEMY_TOLERANCE_CLOSE_DIST_SQR && GetEnemy()->GetEnemy() == GetOuter() )	
		{
			// Only become scared of an enemy at this range if they're my enemy, too
			SetCondition( COND_FEAR_ENEMY_CLOSE );
			if( IsInASafePlace() )
			{
				SpoilSafePlace();
			}
		}
	}

	ClearCondition(COND_FEAR_SEPARATED_FROM_PLAYER);

	// Check for separation from the player
	//	-The player is farther away than 60 feet
	//  -I haven't seen the player in 2 seconds
	//
	// Here's the distance check:
	CBasePlayer *pPlayer = AI_GetSinglePlayer();
	if( pPlayer != NULL && GetAbsOrigin().DistToSqr(pPlayer->GetAbsOrigin()) >= Square( ai_fear_player_dist.GetFloat() * 1.5f )  )
	{
		SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER);
	}

	// Here's the visibility check. We can't skip this because it's time-sensitive
	if( GetOuter()->FVisible(pPlayer) )
	{
		m_flTimePlayerLastVisible = gpGlobals->curtime;
	}
	else
	{
		if( gpGlobals->curtime - m_flTimePlayerLastVisible >= 2.0f )
		{
			SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER);
		}
	}

	if( HasCondition(COND_FEAR_SEPARATED_FROM_PLAYER) )
	{
		//Msg("I am separated from player\n");

		if( IsInASafePlace() )
		{
			SpoilSafePlace();
		}
	}
}
Ejemplo n.º 26
0
int CAI_LeadBehavior::SelectSchedule()
{
	if ( HasGoal() )
	{
		if( HasCondition(COND_LEAD_SUCCESS) )
		{
			return SCHED_LEAD_SUCCEED;
		}

		// Player's here, but does he have the weapon we want him to have?
		if ( m_weaponname != NULL_STRING )
		{
			CBasePlayer *pFollower = AI_GetSinglePlayer();
			if ( pFollower && !pFollower->Weapon_OwnsThisType( STRING(m_weaponname) ) )
			{
				// If the safety timeout has run out, just give the player the weapon
				if ( !m_flWeaponSafetyTimeOut || (m_flWeaponSafetyTimeOut > gpGlobals->curtime) )
					return SCHED_LEAD_PLAYERNEEDSWEAPON;

				string_t iszItem = AllocPooledString( "weapon_bugbait" );
				pFollower->GiveNamedItem( STRING(iszItem) );
			}
		}

		// If we have a waitpoint, we want to wait at it for the player.
		if( HasWaitPoint() && !PlayerIsAheadOfMe( true ) )
		{
			bool bKeepWaiting = true;

			// If we have no wait distance, trigger as soon as the player comes in view
			if ( !m_waitdistance )
			{
				if ( HasCondition( COND_SEE_PLAYER ) )
				{
					// We've spotted the player, so stop waiting
					bKeepWaiting = false;
				}
			}
			else
			{
				// We have to collect data about the person we're leading around.
				CBaseEntity *pFollower = AI_GetSinglePlayer();
				if( pFollower )
				{
					float flFollowerDist = ( WorldSpaceCenter() - pFollower->WorldSpaceCenter() ).Length();
					if ( flFollowerDist < m_waitdistance )
					{
						bKeepWaiting = false;
					}
				}
			}

			// Player still not here?
			if ( bKeepWaiting )
				return SCHED_LEAD_WAITFORPLAYER;

			// We're finished waiting
			m_waitpoint = vec3_origin;
			Speak( TLK_LEAD_WAITOVER );

			// Don't speak the start line, because we've said 
			m_hasspokenstart = true;
			return SCHED_WAIT_FOR_SPEAK_FINISH;
		}

		// If we haven't spoken our start speech, do that first
		if ( !m_hasspokenstart )
		{
			if ( HasCondition(COND_LEAD_HAVE_FOLLOWER_LOS) && HasCondition(COND_LEAD_FOLLOWER_VERY_CLOSE) )
				return SCHED_LEAD_SPEAK_START;

			// We haven't spoken to him, and we still need to. Go get him.
			return SCHED_LEAD_RETRIEVE;
		}

		if( HasCondition( COND_LEAD_FOLLOWER_LOST ) )
		{
			if( m_args.iRetrievePlayer )
			{
				// If not, we want to go get the player.
				DevMsg( GetOuter(), "Follower lost. Spoke COMING_BACK.\n");

				Speak( TLK_LEAD_COMINGBACK );
				m_MoveMonitor.ClearMark();

				// If we spoke something, wait for it to finish
				if ( m_args.iComingBackWaitForSpeak && IsSpeaking() )
					return SCHED_LEAD_SPEAK_THEN_RETRIEVE_PLAYER;

				return SCHED_LEAD_RETRIEVE;
			}
			else
			{
				// Just stay right here and wait.
				return SCHED_LEAD_WAITFORPLAYERIDLE;
			}
		}

		if( HasCondition( COND_LEAD_FOLLOWER_LAGGING ) )
		{
			DevMsg( GetOuter(), "Follower lagging. Spoke CATCHUP.\n");

			Speak( TLK_LEAD_CATCHUP );
			return SCHED_LEAD_PAUSE;
		}
		else
		{
			// If we're at the goal, wait for the player to get here
			if ( ( WorldSpaceCenter() - m_goal ).LengthSqr() < (64*64) )
				return SCHED_LEAD_AWAIT_SUCCESS;

			// If we were retrieving the player, speak the resume
			if ( IsCurSchedule( SCHED_LEAD_RETRIEVE, false ) || IsCurSchedule( SCHED_LEAD_WAITFORPLAYERIDLE, false ) )
			{
				Speak( TLK_LEAD_RETRIEVE );

				// If we spoke something, wait for it to finish, if the mapmakers wants us to
				if ( m_args.iRetrieveWaitForSpeak && IsSpeaking() )
					return SCHED_LEAD_SPEAK_THEN_LEAD_PLAYER;
			}

			DevMsg( GetOuter(), "Leading Follower.\n");
			return SCHED_LEAD_PLAYER;
		}
	}
	return BaseClass::SelectSchedule();
}
Ejemplo n.º 27
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CAI_LeadBehavior::GatherConditions( void )
{
	BaseClass::GatherConditions();

	if ( HasGoal() )
	{
		// Fix for bad transition case (to investigate)
		if ( ( WorldSpaceCenter() - m_goal ).LengthSqr() > (64*64) && IsCurSchedule( SCHED_LEAD_AWAIT_SUCCESS, false)  )
		{
			GetOuter()->ClearSchedule( "Lead behavior - bad transition?" );
		}

		// We have to collect data about the person we're leading around.
		CBaseEntity *pFollower = AI_GetSinglePlayer();

		if( pFollower )
		{
			ClearCondition( COND_LEAD_FOLLOWER_VERY_CLOSE );
			ClearCondition( COND_LEAD_FOLLOWER_MOVING_TOWARDS_ME );

			// Check distance to the follower
			float flFollowerDist = ( WorldSpaceCenter() - pFollower->WorldSpaceCenter() ).Length();
			bool bLagging = flFollowerDist > (m_leaddistance*4);
			if ( bLagging )
			{
				if ( PlayerIsAheadOfMe() )
				{
					bLagging = false;
				}
			}

			// Player heading towards me?
			// Only factor this in if you're not too far from them
			if ( flFollowerDist < (m_leaddistance*4) )
			{
				Vector vecVelocity = pFollower->GetSmoothedVelocity();
				if ( VectorNormalize(vecVelocity) > 50 )
				{
					Vector vecToPlayer = (GetAbsOrigin() - pFollower->GetAbsOrigin());
					VectorNormalize( vecToPlayer );
					if ( DotProduct( vecVelocity, vecToPlayer ) > 0.5 )
					{
						SetCondition( COND_LEAD_FOLLOWER_MOVING_TOWARDS_ME );
						bLagging = false;
					}
				}
			}

			// If he's outside our lag range, consider him lagging
			if ( bLagging )
			{
				SetCondition( COND_LEAD_FOLLOWER_LAGGING );
				ClearCondition( COND_LEAD_FOLLOWER_NOT_LAGGING );
			}
			else
			{
				ClearCondition( COND_LEAD_FOLLOWER_LAGGING );
				SetCondition( COND_LEAD_FOLLOWER_NOT_LAGGING );

				// If he's really close, note that
				if ( flFollowerDist < m_leaddistance )
				{
					SetCondition( COND_LEAD_FOLLOWER_VERY_CLOSE );
				}
			}

			// To be considered not lagging, the follower must be visible, and within the lead distance
			if ( GetOuter()->FVisible( pFollower ) && GetOuter()->GetSenses()->ShouldSeeEntity( pFollower ) )
			{
				SetCondition( COND_LEAD_HAVE_FOLLOWER_LOS );
				m_LostLOSTimer.Stop();
			}
			else
			{
				ClearCondition( COND_LEAD_HAVE_FOLLOWER_LOS );

				// We don't have a LOS. But if we did have LOS, don't clear it until the timer is up.
				if ( m_LostLOSTimer.IsRunning() )
				{
					if ( m_LostLOSTimer.Expired() )
					{
						SetCondition( COND_LEAD_FOLLOWER_LAGGING );
						ClearCondition( COND_LEAD_FOLLOWER_NOT_LAGGING );
					}
				}
				else
				{
					m_LostLOSTimer.Start();
				}
			}

			// Now we want to see if the follower is lost. Being lost means being (far away || out of LOS ) 
			// && some time has passed. Also, lagging players are considered lost if the NPC's never delivered
			// the start speech, because it means the NPC should run to the player to start the lead.
			if( HasCondition( COND_LEAD_FOLLOWER_LAGGING ) )
			{
				if ( !m_hasspokenstart )
				{
					SetCondition( COND_LEAD_FOLLOWER_LOST );
				}
				else
				{
					if ( m_args.bStopScenesWhenPlayerLost )
					{
						// Try and stop me speaking my monolog, if I am
						if ( !m_hasPausedScenes && IsRunningScriptedScene( GetOuter() ) )
						{
							//Msg("Stopping scenes.\n");
							PauseActorsScriptedScenes( GetOuter(), false );
							m_hasPausedScenes = true;
						}
					}

					if( m_LostTimer.IsRunning() )
					{
						if( m_LostTimer.Expired() )
						{
							SetCondition( COND_LEAD_FOLLOWER_LOST );
						}
					}
					else
					{
						m_LostTimer.Start();
					}
				}
			}
			else
			{
				// If I was speaking a monolog, resume it
				if ( m_args.bStopScenesWhenPlayerLost && m_hasPausedScenes )
				{
					if ( IsRunningScriptedScene( GetOuter() ) )
					{
						//Msg("Resuming scenes.\n");
						ResumeActorsScriptedScenes( GetOuter(), false );
					}

					m_hasPausedScenes = false;
				}

				m_LostTimer.Stop();
				ClearCondition( COND_LEAD_FOLLOWER_LOST );
			}

			// Evaluate for success
			// Success right now means being stationary, close to the goal, and having the player close by
			if ( !( m_args.flags & AILF_NO_DEF_SUCCESS ) )
			{
				ClearCondition( COND_LEAD_SUCCESS );

				// Check Z first, and only check 2d if we're within that
				bool bWithinZ = fabs(GetLocalOrigin().z - m_goal.z) < 64;
				if ( bWithinZ && (GetLocalOrigin() - m_goal).Length2D() <= 64 )
				{
					if ( HasCondition( COND_LEAD_FOLLOWER_VERY_CLOSE ) )
					{
						SetCondition( COND_LEAD_SUCCESS );
					}
					else if ( m_successdistance )
					{
						float flDistSqr = (pFollower->GetAbsOrigin() - GetLocalOrigin()).Length2DSqr();
						if ( flDistSqr < (m_successdistance*m_successdistance) )
						{
							SetCondition( COND_LEAD_SUCCESS );
						}
					}
				}
			}
			if ( m_MoveMonitor.IsMarkSet() && m_MoveMonitor.TargetMoved( pFollower ) )
				SetCondition( COND_LEAD_FOLLOWER_MOVED_FROM_MARK );
			else
				ClearCondition( COND_LEAD_FOLLOWER_MOVED_FROM_MARK );
		}
	}

	if( m_args.bLeadDuringCombat )
	{
		ClearCondition( COND_LIGHT_DAMAGE );
		ClearCondition( COND_HEAVY_DAMAGE );
	}
}
Ejemplo n.º 28
0
void CNPC_Dog::ThrowObject( const char *pAttachmentName )
{
	if ( m_hPhysicsEnt )
	{
		m_bHasObject = false;

		IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject();

		if ( pPhysObj )
		{
			Vector vGunPos;
			QAngle angGunAngles;

			AngularImpulse angVelocity = RandomAngularImpulse( -250 , -250 ) / pPhysObj->GetMass();

			InvalidateBoneCache();

			int iAttachment = LookupAttachment( pAttachmentName );

			if ( iAttachment == 0 )
				 iAttachment = m_iPhysGunAttachment;
			
			GetAttachment( iAttachment, vGunPos, angGunAngles );

			pPhysObj->Wake();

			if ( pPhysObj->GetShadowController() )
			{
				m_hPhysicsEnt->SetParent( NULL );
				m_hPhysicsEnt->SetMoveType( (MoveType_t)m_iContainerMoveType );
				m_hPhysicsEnt->SetOwnerEntity( this );

				pPhysObj->RemoveShadowController();
				pPhysObj->SetPosition( m_hPhysicsEnt->GetLocalOrigin(), m_hPhysicsEnt->GetLocalAngles(), true );

				pPhysObj->RecheckCollisionFilter();
				pPhysObj->RecheckContactPoints();
			}
				
			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

			Vector vThrowDirection;

			if ( m_hThrowTarget )
			{
				Vector vThrowOrigin = m_hThrowTarget->GetAbsOrigin();
				
				if ( m_hThrowTarget->IsPlayer() )
					 vThrowOrigin = vThrowOrigin + Vector( random->RandomFloat( -128, 128 ), random->RandomFloat( -128, 128 ), 0 );

				Vector vecToss = VecCheckToss( this, vGunPos, vThrowOrigin, m_flThrowArcModifier, 1.0f, true );

				if( vecToss == vec3_origin )
				{
					// Fix up an impossible throw so dog will at least toss the box in the target's general direction instead of dropping it.
					// Also toss it up in the air so it will fall down and break. (Just throw the box up at a 45 degree angle)
					Vector forward, up;
					GetVectors( &forward, NULL, &up );

					vecToss = forward + up;
					VectorNormalize( vecToss );

					vecToss *= pPhysObj->GetMass() * 30.0f;
				}

				vThrowDirection = vecToss + ( m_hThrowTarget->GetSmoothedVelocity() / 2 );
							
				Vector vLinearDrag;

				Vector unitVel = vThrowDirection;
				VectorNormalize( unitVel );

				float flTest = 1000 / vThrowDirection.Length();

				float flDrag = pPhysObj->CalculateLinearDrag( vThrowDirection );
				vThrowDirection = vThrowDirection + ( unitVel * ( flDrag * flDrag ) ) / flTest;
			
				pPhysObj->SetVelocity( &vThrowDirection, &angVelocity );
				
				m_flTimeToCatch = gpGlobals->curtime + dog_max_wait_time.GetFloat();

				//Don't start pulling until the object is away from me.
				//We base the time on the throw velocity.
				m_flTimeToPull = gpGlobals->curtime + ( 1000 / vThrowDirection.Length() );
			}

			//Fire Output!
			m_OnThrow.FireOutput( this, this );

			ClearBeams();
			
			if ( m_bBeamEffects == true )
			{
				EmitSound( "Weapon_PhysCannon.Launch" );
				
				CBeam *pBeam = CBeam::BeamCreate(  "sprites/orangelight1.vmt", 1.8 );

				if ( pBeam != NULL )
				{
					pBeam->PointEntInit( m_hPhysicsEnt->WorldSpaceCenter(), this );
					pBeam->SetEndAttachment( m_iPhysGunAttachment );
					pBeam->SetWidth( 6.4 );
					pBeam->SetEndWidth( 12.8 );					
					pBeam->SetBrightness( 255 );
					pBeam->SetColor( 255, 255, 255 );
					pBeam->LiveForTime( 0.2f );
					pBeam->RelinkBeam();
					pBeam->SetNoise( 2 );
				}
			
				Vector	shotDir = ( m_hPhysicsEnt->WorldSpaceCenter() - vGunPos );
				VectorNormalize( shotDir );

				CPVSFilter filter( m_hPhysicsEnt->WorldSpaceCenter() );
				te->GaussExplosion( filter, 0.0f, m_hPhysicsEnt->WorldSpaceCenter() - ( shotDir * 4.0f ), RandomVector(-1.0f, 1.0f), 0 );
			}
		}
	}
}
Ejemplo n.º 29
0
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);
	}
}
Ejemplo n.º 30
0
void CAI_ScriptConditions::EvaluationThink()
{
	if ( m_fDisabled == true )
		return;

	int iActorsDone = 0;

#ifdef HL2_DLL
	if( AI_GetSinglePlayer()->GetFlags() & FL_NOTARGET )
	{
		ScrCondDbgMsg( ("%s WARNING: Player is NOTARGET. This will affect all LOS conditiosn involving the player!\n", GetDebugName()) );
	}
#endif


	for ( int i = 0; i < m_ElementList.Count(); )
	{
		CAI_ScriptConditionsElement *pConditionElement = &m_ElementList[i];

		if ( pConditionElement == NULL )
		{
			i++;
			continue;
		}

		CBaseEntity *pActor = pConditionElement->GetActor();
		CBaseEntity *pActivator = this;

#ifdef HL2_EPISODIC
		if ( pActor && HasSpawnFlags( SF_ACTOR_AS_ACTIVATOR ) )
		{
			pActivator = pActor;
		}
#endif

		AssertMsg( !m_fDisabled, ("Violated invariant between CAI_ScriptConditions disabled state and think func setting") );

		if ( m_Actor != NULL_STRING && !pActor )
		{
			if ( m_ElementList.Count() == 1 )
			{
				DevMsg( "Warning: Active AI script conditions associated with an non-existant or destroyed NPC\n" );
				m_NoValidActors.FireOutput( this, this, 0 );
			}

			iActorsDone++;
			m_ElementList.Remove( i );
			continue;
		}

		i++;

		if( m_flMinTimeout > 0 && pConditionElement->GetTimeOut()->Expired() )
		{
			ScrCondDbgMsg( ( "%s firing output OnConditionsTimeout (%f seconds)\n", STRING( GetEntityName() ), pConditionElement->GetTimeOut()->GetInterval() ) );

			iActorsDone++;
			m_OnConditionsTimeout.FireOutput( pActivator, this );
			continue;
		}

		bool      result = true;
		const int nEvaluators = sizeof( gm_Evaluators ) / sizeof( gm_Evaluators[0] );

		EvalArgs_t args =
		{
			pActor,
			GetPlayer(),
			m_hTarget.Get()
		};

		for ( int i = 0; i < nEvaluators; ++i )
		{
			if ( !(this->*gm_Evaluators[i].pfnEvaluator)( args ) )
			{
				pConditionElement->GetTimer()->Reset();
				result = false;

				ScrCondDbgMsg( ( "%s failed on: %s\n", GetDebugName(), gm_Evaluators[ i ].pszName ) );

				break;
			}
		}

		if ( result )
		{
			ScrCondDbgMsg( ( "%s waiting... %f\n", GetDebugName(), pConditionElement->GetTimer()->GetRemaining() ) );
		}

		if ( result && pConditionElement->GetTimer()->Expired() )
		{
			ScrCondDbgMsg( ( "%s firing output OnConditionsSatisfied\n", GetDebugName() ) );

			// Default behavior for now, provide worldcraft option later.
			iActorsDone++;
			m_OnConditionsSatisfied.FireOutput( pActivator, this );
		}
	}

	//All done!
	if ( iActorsDone == m_ElementList.Count() )
	{
		Disable();
		m_ElementList.Purge();
	}

	SetThinkTime();
}