Ejemplo n.º 1
0
int CNPC_Vortigaunt::TranslateSchedule( int scheduleType )
{
    //Oops can't get to my enemy.
    if ( scheduleType == SCHED_CHASE_ENEMY_FAILED )
    {
        return SCHED_ESTABLISH_LINE_OF_FIRE;
    }

    switch	( scheduleType )
    {
    case SCHED_FAIL:

        if ( HasCondition( COND_CAN_MELEE_ATTACK1 ) )
        {
            return ( SCHED_MELEE_ATTACK1 );
        }

        break;

    case SCHED_RANGE_ATTACK1:
    {
        //Adrian - HACK HACK! This should've been done up there ^^^^
        if ( HasCondition( COND_CAN_MELEE_ATTACK1 ) )
        {
            return ( SCHED_MELEE_ATTACK1 );
        }

        return SCHED_VORTIGAUNT_ATTACK;
    }

    break;
    }

    return BaseClass::TranslateSchedule( scheduleType );
}
Ejemplo n.º 2
0
//---------------------------------------------------------
//---------------------------------------------------------
int CNPC_Roller::SelectSchedule ( void )
{
	if( m_fHACKJustSpawned )
	{
		m_fHACKJustSpawned = false;
		return SCHED_ROLLER_WAIT_FOR_PHYSICS;
	}

	switch( m_NPCState )
	{
	case NPC_STATE_COMBAT:
		if( HasCondition( COND_ROLLER_PHYSICS ) )
		{
			return SCHED_ROLLER_WAIT_FOR_PHYSICS;
		}
		break;

	default:
		if( HasCondition( COND_ROLLER_PHYSICS ) )
		{
			return SCHED_ROLLER_WAIT_FOR_PHYSICS;
		}

		return SCHED_IDLE_STAND;
		break;
	}

	return SCHED_IDLE_STAND;
}
Ejemplo n.º 3
0
//------------------------------------------------------------------------------
// Purpose: routine called to select what schedule we want to run
// Output : returns the schedule id of the schedule we want to run
//------------------------------------------------------------------------------
int CAI_ASW_ShieldBehavior::SelectSchedule()
{
	if ( !HasCondition( COND_CAN_MELEE_ATTACK2 ) )
	{
		return SCHED_SHIELD_LOWER;
	}

	if ( GetBehaviorParam( m_StatusParm ) == 0 )
	{
		return SCHED_SHIELD_PREPARE;
	}
	else
	{
		return SCHED_SHIELD_MAINTAIN;
	}

#if 0
	if ( m_bShieldLowering == true )
	{
		return SCHED_SHIELD_LOWER;
	}

	if ( GetBehaviorParam( m_StatusParm ) == 0 )
	{
		return SCHED_SHIELD_PREPARE;
	}

	if ( HasCondition( COND_SHIELD_CAN_FLICK ) )
	{
		return SCHED_SHIELD_FLICK;
	}

	return SCHED_SHIELD_MAINTAIN;
#endif
}
Ejemplo n.º 4
0
int CNPC_Hydra::SelectSchedule ()
{
	switch ( m_NPCState )
	{
	case NPC_STATE_IDLE:
		{
			SetState( NPC_STATE_ALERT );
			return SCHED_HYDRA_DEPLOY;
		}
		break;

	case NPC_STATE_ALERT:
		{
			return SCHED_HYDRA_STAB;
		}
		break;

	case NPC_STATE_COMBAT:
		{
			if (HasCondition( COND_HYDRA_SNAGGED ))
			{
				return SCHED_HYDRA_PULLBACK;
			}
			else if (HasCondition( COND_HYDRA_OVERSTRETCH ))
			{
				return SCHED_HYDRA_STAB;
			}
			return SCHED_HYDRA_STAB;
		}
		break;	
	}

	return BaseClass::SelectSchedule();
}
Ejemplo n.º 5
0
// note: mostly copied from shover parent (no clean way to call up and extend), with the jump part added
int	CASW_Alien_Jumper::SelectCombatSchedule( void )
{
	//Physics target
	if ( HasCondition( COND_ALIEN_SHOVER_PHYSICS_TARGET ) )
	{
		//Msg("Alien shoving physics object from selectcombatschedule\n");
		return SCHED_ALIEN_SHOVER_PHYSICS_ATTACK;
	}

	// Attack if we can
	if ( HasCondition(COND_CAN_MELEE_ATTACK1) )
		return SCHED_MELEE_ATTACK1;

	// See if we can bash what's in our way, or roar
	if ( HasCondition( COND_ENEMY_UNREACHABLE ) )
	{
		int iUnreach = SelectUnreachableSchedule();
		if (iUnreach != -1)
			return iUnreach;
	}

	// Try to jump
	if ( HasCondition( COND_ASW_ALIEN_CAN_JUMP ) )
		return SCHED_ASW_ALIEN_JUMP;

	return BaseClass::BaseClass::SelectSchedule();
}
//================================================================================
//================================================================================
float CHuntEnemySchedule::GetDesire() const
{
    if ( !GetMemory() || !GetLocomotion() )
        return BOT_DESIRE_NONE;

    if ( !GetDecision()->CanHuntThreat() )
        return BOT_DESIRE_NONE;

    CEntityMemory *memory = GetBot()->GetPrimaryThreat();

    if ( memory == NULL )
        return BOT_DESIRE_NONE;

    // We have no vision of the enemy
    if ( HasCondition( BCOND_ENEMY_LOST ) ) {
        // But we have a vision of his last position and we are close
        if ( HasCondition( BCOND_ENEMY_LAST_POSITION_VISIBLE ) && (HasCondition( BCOND_ENEMY_TOO_NEAR ) || HasCondition( BCOND_ENEMY_NEAR )) )
            return BOT_DESIRE_NONE;
        
        return 0.65f;
    }

    // We do not have direct vision to the enemy (a person, window, etc.)
    if ( HasCondition( BCOND_ENEMY_OCCLUDED ) )
        return 0.65f;

    // We do not have range of attack
    if ( HasCondition( BCOND_TOO_FAR_TO_ATTACK ) )
        return 0.38f;

    return BOT_DESIRE_NONE;
}
NPC_STATE CNPC_Cremator::SelectIdealState( void )
{
	switch( m_NPCState )
	{
	case NPC_STATE_COMBAT:
		{
			if ( GetEnemy() == NULL )
			{
				if ( !HasCondition( COND_ENEMY_DEAD ) )
				{
					SetCondition( COND_ENEMY_DEAD ); // TODO: patrolling

				}
				return NPC_STATE_ALERT;
			}
			else if ( HasCondition( COND_ENEMY_DEAD ) )
			{
				//AnnounceEnemyKill(GetEnemy());
			}
		}
	default:
		{
			return BaseClass::SelectIdealState();
		}
	}

	return GetIdealState();
}
int CAI_StandoffBehavior::SelectScheduleUpdateWeapon( void )
{
	// Check if need to reload
	if ( HasCondition ( COND_NO_PRIMARY_AMMO ) || HasCondition ( COND_LOW_PRIMARY_AMMO ))
	{
		if ( m_params.fCoverOnReload )
			return SCHED_HIDE_AND_RELOAD;
		else
			return SCHED_RELOAD;
	}
	
	// Otherwise, update planned shots to fire before taking cover again
	if ( HasCondition( COND_LIGHT_DAMAGE ) )
	{
		// if hurt:
		int iPercent = random->RandomInt(0,99);

		if ( iPercent <= m_params.oddsCover && GetEnemy() != NULL )
		{
			SetReuseCurrentCover();
			m_ShotRegulator.SetShots( ( m_ShotRegulator.GetShots() > 1 ) ? 1 : 0 );
		}
	}

	m_ShotRegulator.Update();

	return SCHED_NONE;
}
int CAI_StandoffBehavior::SelectScheduleUpdateWeapon( void )
{
	// Check if need to reload
	if ( HasCondition ( COND_NO_PRIMARY_AMMO ) || HasCondition ( COND_LOW_PRIMARY_AMMO ))
	{
		StandoffMsg( "Out of ammo, reloading\n" );
		if ( m_params.fCoverOnReload )
		{
			GetOuter()->SpeakSentence( STANDOFF_SENTENCE_OUT_OF_AMMO );
			return SCHED_HIDE_AND_RELOAD;
		}
		
		return SCHED_RELOAD;
	}
	
	// Otherwise, update planned shots to fire before taking cover again
	if ( HasCondition( COND_LIGHT_DAMAGE ) )
	{
		// if hurt:
		int iPercent = random->RandomInt(0,99);

		if ( iPercent <= m_params.oddsCover && GetEnemy() != NULL )
		{
			SetReuseCurrentCover();
			StandoffMsg( "Hurt, firing one more shot before cover\n" );
			if ( !GetOuter()->GetShotRegulator()->IsInRestInterval() )
			{
				GetOuter()->GetShotRegulator()->SetBurstShotsRemaining( 1 );
			}
		}
	}

	return SCHED_NONE;
}
Ejemplo n.º 10
0
//---------------------------------------------------------
//---------------------------------------------------------
void CNPC_GroundTurret::GatherConditions()
{
	if( !IsEnabled() )
	{
		return;
	}

	if( !IsOpen() && !UTIL_FindClientInPVS( edict() ) )
	{
		return;
	}

	// Throw away old enemies so the turret can retire
	AIEnemiesIter_t iter;

	for( AI_EnemyInfo_t *pEMemory = GetEnemies()->GetFirst(&iter); pEMemory != NULL; pEMemory = GetEnemies()->GetNext(&iter) )
	{
		if( pEMemory->timeLastSeen < gpGlobals->curtime - GROUNDTURRET_RETIRE_TIME )
		{
			pEMemory->hEnemy = NULL;
		}
	}

	BaseClass::GatherConditions();

	if( GetEnemy() && HasCondition(COND_SEE_ENEMY) )
	{
		m_flTimeLastSawEnemy = gpGlobals->curtime;
	}
	else
	{
		if( gpGlobals->curtime - m_flTimeLastSawEnemy >= GROUNDTURRET_RETIRE_TIME )
		{
			m_OnAreaClear.FireOutput(this, this);
			m_flTimeLastSawEnemy = FLT_MAX;
			return;
		}
	}

	if( HasCondition( COND_SEE_ENEMY ) )
	{
		m_bSeeEnemy = true;
	}
	else
	{
		m_bSeeEnemy = false;
	}

	if( GetEnemy() && m_bSeeEnemy && IsEnabled() )
	{
		if( m_flTimeNextShoot < gpGlobals->curtime )
		{
			Shoot();
		}
	}
}
Ejemplo n.º 11
0
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() );
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &vecTarget - 
// Output : float
//-----------------------------------------------------------------------------
float CNPC_Bug_Warrior::CalcIdealYaw( const Vector &vecTarget )
{
	//If we can see our enemy but not reach them, face them always
	if ( ( GetEnemy() != NULL ) && ( HasCondition( COND_SEE_ENEMY ) && HasCondition( COND_ENEMY_UNREACHABLE ) ) )
	{
		return UTIL_VecToYaw ( GetEnemy()->GetAbsOrigin() - GetAbsOrigin() );
	}

	return BaseClass::CalcIdealYaw( vecTarget );
}
bool CNPC_Tentacle::HeardAnything( void )
{
	if ( HasCondition( COND_HEAR_DANGER ) || // I remove a bunch of sounds from here on purpose. Talk to me if you're changing this!(sjb)
		 HasCondition( COND_HEAR_COMBAT ) ||
		 HasCondition( COND_HEAR_WORLD )  ||
		 HasCondition( COND_HEAR_PLAYER ) )
		 return true;

	return false;
}
//-----------------------------------------------------------------------------
// Purpose: Move the zombie to the vehicle
//-----------------------------------------------------------------------------
int CAI_PassengerBehaviorZombie::SelectSchedule( void )
{
	// See if our enemy got out
	if ( GetOuter()->GetEnemy() != NULL && EnemyInVehicle() == false  )
	{
		if ( GetPassengerState() == PASSENGER_STATE_INSIDE )
		{
			// Exit the vehicle
			SetCondition( COND_PASSENGER_EXITING );
		}
		else if ( GetPassengerState() == PASSENGER_STATE_OUTSIDE )
		{
			// Our target has left the vehicle and we're outside as well, so give up
			Disable();
			return BaseClass::SelectSchedule();
		}
	}

	// Entering schedule
	if ( HasCondition( COND_PASSENGER_ENTERING ) )
	{
		ClearCondition( COND_PASSENGER_ENTERING );
		return SCHED_PASSENGER_ZOMBIE_ENTER_VEHICLE;
	}

	// Exiting schedule
	if ( HasCondition( COND_PASSENGER_EXITING ) )
	{
		ClearCondition( COND_PASSENGER_EXITING );
		return SCHED_PASSENGER_ZOMBIE_EXIT_VEHICLE;
	}

	// Select different schedules based on our state
	PassengerState_e nState = GetPassengerState();
	int nNewSchedule = SCHED_NONE;

	if ( nState == PASSENGER_STATE_INSIDE )
	{
		nNewSchedule = SelectInsideSchedule();
		if ( nNewSchedule != SCHED_NONE )
			return nNewSchedule;
	}
	else if ( nState == PASSENGER_STATE_OUTSIDE )
	{
		nNewSchedule = SelectOutsideSchedule();
		if ( nNewSchedule != SCHED_NONE )
			return nNewSchedule;
	}

	// Worst case he just stands here
	Assert(0);
	return SCHED_IDLE_STAND;
}
Ejemplo n.º 15
0
//=========================================================
// CheckRangeAttack1 
//
// !!!LATER - we may want to load balance this. Several
// tracelines are done, so we may not want to do this every
// server frame. Definitely not while firing. 
//=========================================================
int CNPC_AlienGrunt::RangeAttack1Conditions ( float flDot, float flDist )
{
	if ( gpGlobals->curtime < m_flNextHornetAttackCheck )
	{
		if ( HasCondition( COND_SEE_ENEMY ) )
		{
			if ( m_fCanHornetAttack == true )
			{
				 return COND_CAN_RANGE_ATTACK1;
			}
			else
			{
				return COND_NONE;
			}
		}
		else
			return COND_NONE;
	}

	if ( flDist < AGRUNT_MELEE_DIST )
		 return COND_NONE;

	if ( flDist > 1024 )
		 return COND_NONE;

	if ( flDot < 0.5 )
		 return COND_NONE;
	
	if ( HasCondition( COND_SEE_ENEMY ) )
	{
		trace_t tr;
		Vector	vecArmPos;
		QAngle	angArmDir;
		
		// verify that a shot fired from the gun will hit the enemy before the world.
		// !!!LATER - we may wish to do something different for projectile weapons as opposed to instant-hit
		GetAttachment( "0", vecArmPos, angArmDir );
		UTIL_TraceLine( vecArmPos, GetEnemy()->BodyTarget( vecArmPos ), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);
		
		if ( tr.fraction == 1.0 || tr.m_pEnt == GetEnemy() )
		{
			m_flNextHornetAttackCheck = gpGlobals->curtime + random->RandomFloat( 2, 5 );
			m_fCanHornetAttack = true;
			
			return COND_CAN_RANGE_ATTACK1;
		}
	}
	
	m_flNextHornetAttackCheck = gpGlobals->curtime + 0.2;// don't check for half second if this check wasn't successful
	m_fCanHornetAttack = false;
	return COND_NONE;
}
Ejemplo n.º 16
0
void CNPC_Stalker::AddZigZagToPath(void) 
{
	// If already on a detour don't add a zigzag
	if (GetNavigator()->GetCurWaypointFlags() & bits_WP_TO_DETOUR)
	{
		return;
	}

	// If enemy isn't facing me or occluded, don't add a zigzag
	if (HasCondition(COND_ENEMY_OCCLUDED) || !HasCondition ( COND_ENEMY_FACING_ME ))
	{
		return;
	}

	Vector waypointPos = GetNavigator()->GetCurWaypointPos();
	Vector waypointDir = (waypointPos - GetAbsOrigin());

	// If the distance to the next node is greater than ZIG_ZAG_SIZE
	// then add a random zig/zag to the path
	if (waypointDir.LengthSqr() > ZIG_ZAG_SIZE)
	{
		// Pick a random distance for the zigzag (less that sqrt(ZIG_ZAG_SIZE)
		float distance = random->RandomFloat( 30, 60 );

		// Get me a vector orthogonal to the direction of motion
		VectorNormalize( waypointDir );
		Vector vDirUp(0,0,1);
		Vector vDir;
		CrossProduct( waypointDir, vDirUp, vDir);

		// Pick a random direction (left/right) for the zigzag
		if (random->RandomInt(0,1))
		{
			vDir = -1 * vDir;
		}

		// Get zigzag position in direction of target waypoint
		Vector zigZagPos = GetAbsOrigin() + waypointDir * 60;

		// Now offset 
		zigZagPos = zigZagPos + (vDir * distance);

		// Now make sure that we can still get to the zigzag position and the waypoint
		AIMoveTrace_t moveTrace1, moveTrace2;
		GetMoveProbe()->MoveLimit( NAV_GROUND, GetAbsOrigin(), zigZagPos, GetAITraceMask(), NULL, &moveTrace1);
		GetMoveProbe()->MoveLimit( NAV_GROUND, zigZagPos, waypointPos, GetAITraceMask(), NULL, &moveTrace2);
		if ( !IsMoveBlocked( moveTrace1 ) && !IsMoveBlocked( moveTrace2 ) )
		{
			GetNavigator()->PrependWaypoint( zigZagPos, NAV_GROUND, bits_WP_TO_DETOUR );
		}
	}
}
//------------------------------------------------------------------------------
// Purpose: routine called to select what schedule we want to run
// Output : returns the schedule id of the schedule we want to run
//------------------------------------------------------------------------------
int CAI_ASW_HealOtherBehavior::SelectSchedule()
{
	if ( HasCondition( COND_HEAL_OTHER_NOT_HAS_TARGET ) || HasCondition( COND_HEAL_OTHER_HAS_FULL_HEALTH ) || HasCondition( COND_HEAL_OTHER_NOT_TARGET_IN_RANGE ) || HasCondition( COND_HEAL_OTHER_TARGET_CHANGED ) )
	{
		return SCHED_HEAL_OTHER_MOVE_TO_CANDIDATE;
	}
	else
	{
		return SCHED_HEAL_WAIT;
	}

//	return BaseClass::SelectSchedule();
}
//-----------------------------------------------------------------------------
// Purpose: 
//
//
// Output : 
//-----------------------------------------------------------------------------
int CNPC_RollerDozer::SelectSchedule ( void )
{
	if( HasCondition( COND_ROLLERDOZER_FOUND_DEBRIS ) )
	{
		return SCHED_ROLLERDOZER_CLEAR_DEBRIS;
	}

	if( HasCondition( COND_ROLLER_PHYSICS ) )
	{
		m_hDebris = NULL;
	}
	
	return BaseClass::SelectSchedule();
}
Ejemplo n.º 19
0
//------------------------------------------------------------------------------
// Purpose: determines if we can use this behavior currently
// Output : returns true if this behavior is able to run
//------------------------------------------------------------------------------
bool CAI_ASW_RetreatBehavior::CanSelectSchedule()
{
	if ( !GetOuter()->IsInterruptable() )
	{
		return false;
	}

	if ( !HasCondition( COND_LIGHT_DAMAGE ) && !HasCondition( COND_HEAVY_DAMAGE ) )
	{
		return false;
	}

	return BaseClass::CanSelectSchedule();
}
int CNPC_SO_BaseZombie::SelectAlertSchedule()
{
	// Improve zombies' perception of their surroundings
	// http://developer.valvesoftware.com/wiki/AI_Perception_Behavior_Enhancement
	if ( HasCondition ( COND_HEAR_DANGER ) ||
		 HasCondition ( COND_HEAR_PLAYER ) ||
		 HasCondition ( COND_HEAR_WORLD  ) ||
		 HasCondition ( COND_HEAR_BULLET_IMPACT ) ||
		 HasCondition ( COND_HEAR_COMBAT ) )
	{
		return SCHED_INVESTIGATE_SOUND;
	}

	return BaseClass::SelectAlertSchedule();
}
Ejemplo n.º 21
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
int CNPC_VehicleDriver::SelectSchedule( void )
{
	// Vehicle driver hangs in the air inside the vehicle, so we never need to fall to ground
	ClearCondition( COND_FLOATING_OFF_GROUND );

	if ( HasSpawnFlags(SF_VEHICLEDRIVER_INACTIVE) )
	{
		SetState( NPC_STATE_IDLE );
		return SCHED_VEHICLEDRIVER_INACTIVE;
	}

	if ( GetGoalEnt() )
		return SCHED_VEHICLEDRIVER_DRIVE_PATH;

	switch ( m_NPCState )
	{
	case NPC_STATE_IDLE:
		break;

	case NPC_STATE_ALERT:
		break;

	case NPC_STATE_COMBAT:
		{
			if ( HasCondition(COND_NEW_ENEMY) || HasCondition( COND_ENEMY_DEAD ) )
				return BaseClass::SelectSchedule();

			if ( HasCondition(COND_SEE_ENEMY) )
			{
				// we can see the enemy
				if ( HasCondition(COND_CAN_RANGE_ATTACK2) )
					return SCHED_RANGE_ATTACK2;
				if ( HasCondition(COND_CAN_RANGE_ATTACK1) )
					return SCHED_RANGE_ATTACK1;

				// What to do here? Not necessarily easy to face enemy.
				//if ( HasCondition(COND_NOT_FACING_ATTACK) )
					//return SCHED_COMBAT_FACE;
			}

			// We can see him, but can't shoot him. Just wait and hope he comes closer.
			return SCHED_VEHICLEDRIVER_COMBAT_WAIT;
		}
		break;
	}

	return BaseClass::SelectSchedule();
}
//=========================================================
// CheckRangeAttack2 - toss grenade is enemy gets in the way and is too close. 
//=========================================================
int CNPC_HAssassin::RangeAttack2Conditions ( float flDot, float flDist )
{
	m_fThrowGrenade = false;
	if ( !FBitSet ( GetEnemy()->GetFlags(), FL_ONGROUND ) )
	{
		// don't throw grenades at anything that isn't on the ground!
		return COND_NONE;
	}

	// don't get grenade happy unless the player starts to piss you off
	if ( m_iFrustration <= 2)
		return COND_NONE;

	if ( m_flNextGrenadeCheck < gpGlobals->curtime && !HasCondition( COND_ENEMY_OCCLUDED ) && flDist <= 512 )
	{
		Vector vTossPos;
		QAngle vAngles;

		GetAttachment( "grenadehand", vTossPos, vAngles );

		Vector vecToss = VecCheckThrow( this, vTossPos, GetEnemy()->WorldSpaceCenter(), flDist, 0.5 ); // use dist as speed to get there in 1 second

		if ( vecToss != vec3_origin )
		{
			m_vecTossVelocity = vecToss;

			// throw a hand grenade
			m_fThrowGrenade = TRUE;

			return COND_CAN_RANGE_ATTACK2;
		}
	}

	return COND_NONE;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool CRebelZombie::IsHeavyDamage( const CTakeDamageInfo &info )
{
#ifdef HL2_EPISODIC
	if ( info.GetDamageType() & DMG_BUCKSHOT )
	{
		if ( info.GetDamage() > (m_iMaxHealth/3) )
			return true;
	}

	// Randomly treat all damage as heavy
	if ( info.GetDamageType() & (DMG_BULLET | DMG_BUCKSHOT) )
	{
		// Don't randomly flinch if I'm melee attacking
		if ( !HasCondition(COND_CAN_MELEE_ATTACK1) && (RandomFloat() > 0.5) )
		{
			// Randomly forget I've flinched, so that I'll be forced to play a big flinch
			// If this doesn't happen, it means I may not fully flinch if I recently flinched
			if ( RandomFloat() > 0.75 )
			{
				Forget(bits_MEMORY_FLINCHED);
			}

			return true;
		}
	}
#endif // HL2_EPISODIC

	return BaseClass::IsHeavyDamage(info);
}
int CRebelZombie::SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode )
{
	if ( HasCondition( COND_BLOCKED_BY_DOOR ) && m_hBlockingDoor != NULL )
	{
		ClearCondition( COND_BLOCKED_BY_DOOR );
		if ( m_NextTimeToStartDoorBash.Expired() && failedSchedule != SCHED_ZOMBIE_BASH_DOOR )
			return SCHED_ZOMBIE_BASH_DOOR;
		m_hBlockingDoor = NULL;
	}

	if ( failedSchedule != SCHED_ZOMBIE_CHARGE_ENEMY && 
		 IsPathTaskFailure( taskFailCode ) &&
		 random->RandomInt( 1, 100 ) < 50 )
	{
		return SCHED_ZOMBIE_CHARGE_ENEMY;
	}

	if ( failedSchedule != SCHED_ZOMBIE_WANDER_ANGRILY &&
		 ( failedSchedule == SCHED_TAKE_COVER_FROM_ENEMY || 
		   failedSchedule == SCHED_CHASE_ENEMY_FAILED ) )
	{
		return SCHED_ZOMBIE_WANDER_ANGRILY;
	}

	return BaseClass::SelectFailSchedule( failedSchedule, failedTask, taskFailCode );
}
// Выбор скина для глаз крематора в зависимости от обстановки (уместно сравнить с Большими Папочками в Bioshock). В настоящее время не работает.
void CNPC_Cremator::SelectSkin( void ) // doesn't quite work, it can turn eyes red ("combat" skin) when combating an enemy, but will not return to calm/alert skin when an enemy is dead
{
	if(m_NPCState == NPC_STATE_COMBAT)
	{
		m_nSkin = 3;
		if ( HasCondition( COND_ENEMY_DEAD ) )
		{
			m_nSkin = 0;
		}
		if ( GetEnemy() == NULL )
		{
			m_nSkin = 1;
		}
	}
	if(m_NPCState == NPC_STATE_ALERT)
	{
		m_nSkin = 3;
		if ( GetEnemy() == NULL )
		{
			m_nSkin = 1;
		}
	}
	if(m_NPCState == NPC_STATE_NONE)
	{
		m_nSkin = 1;
	}
}
Ejemplo n.º 26
0
//=========================================================
// MeleeAttack2Conditions - bullsquid is a big guy, so has a longer
// melee range than most monsters. This is the bite attack.
// this attack will not be performed if the tailwhip attack
// is valid.
//=========================================================
int CNPC_Bullsquid::MeleeAttack2Conditions( float flDot, float flDist )
{
	if ( flDist <= 85 && flDot >= 0.7 && !HasCondition( COND_CAN_MELEE_ATTACK1 ) )		// The player & bullsquid can be as much as their bboxes 
		 return ( COND_CAN_MELEE_ATTACK2 );
	
	return( COND_NONE );
}
Ejemplo n.º 27
0
int CNPC_APCDriver::RangeAttack2Conditions( float flDot, float flDist )
{
	if ( HasSpawnFlags(SF_APCDRIVER_NO_ROCKET_ATTACK) )
		return COND_NONE;

	if ( m_hAPC->m_lifeState != LIFE_ALIVE )
		return COND_NONE;

	if ( IsBeingCarried() || m_bFiringDisabled )
		return COND_NONE;

	if ( !HasCondition( COND_SEE_ENEMY ) )
		return COND_NONE;

	// Vehicle not ready to fire again yet?
	if ( m_pVehicleInterface->Weapon_SecondaryCanFireAt() > gpGlobals->curtime + 0.1f )
		return COND_NONE;

	float flMinDist, flMaxDist;
	m_pVehicleInterface->Weapon_SecondaryRanges( &flMinDist, &flMaxDist );

	if (flDist < flMinDist)
		return COND_NONE;

	if (flDist > flMaxDist)
		return COND_NONE;

	return COND_CAN_RANGE_ATTACK2;
}
Ejemplo n.º 28
0
void CASW_Parasite::GatherEnemyConditions( CBaseEntity *pEnemy )
{
	// Do the base class
	BaseClass::GatherEnemyConditions( pEnemy );

	// If we're not already too far away, check again
	//TODO: Check to make sure we don't already have a condition set that removes the need for this
	if ( HasCondition( COND_ENEMY_UNREACHABLE ) == false )
	{
		Vector	predPosition;
		UTIL_PredictedPosition( GetEnemy(), 1.0f, &predPosition );

		Vector	predDir = ( predPosition - GetAbsOrigin() );
		float	predLength = VectorNormalize( predDir );

		// See if we'll be outside our effective target range
		if ( predLength > 2000 ) // m_flEludeDistance
		{
			Vector	predVelDir = ( predPosition - GetEnemy()->GetAbsOrigin() );
			float	predSpeed  = VectorNormalize( predVelDir );

			// See if the enemy is moving mostly away from us
			if ( ( predSpeed > 512.0f ) && ( DotProduct( predVelDir, predDir ) > 0.0f ) )
			{
				// Mark the enemy as eluded and burrow away
				ClearEnemyMemory();
				SetEnemy( NULL );
				SetIdealState( NPC_STATE_ALERT );
				SetCondition( COND_ENEMY_UNREACHABLE );
			}
		}
	}
}
Ejemplo n.º 29
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Assassin::GatherEnemyConditions( CBaseEntity *pEnemy )
{
	ClearCondition( COND_ASSASSIN_ENEMY_TARGETTING_ME );

	BaseClass::GatherEnemyConditions( pEnemy );

	// See if we're being targetted specifically
	if ( HasCondition( COND_ENEMY_FACING_ME ) )
	{
		Vector	enemyDir = GetAbsOrigin() - pEnemy->GetAbsOrigin();
		VectorNormalize( enemyDir );

		Vector	enemyBodyDir;
		CBasePlayer	*pPlayer = ToBasePlayer( pEnemy );

		if ( pPlayer != NULL )
		{
			enemyBodyDir = pPlayer->BodyDirection3D();
		}
		else
		{
			AngleVectors( pEnemy->GetAbsAngles(), &enemyBodyDir );
		}

		float	enemyDot = DotProduct( enemyBodyDir, enemyDir );

		//FIXME: Need to refine this a bit
		if ( enemyDot > 0.97f )
		{
			SetCondition( COND_ASSASSIN_ENEMY_TARGETTING_ME );
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: Translate base schedules into overridden forms
//-----------------------------------------------------------------------------
int CAI_BehaviorAlyxInjured::TranslateSchedule( int scheduleType )
{
	switch( scheduleType )
	{
	case SCHED_RUN_FROM_ENEMY:
	case SCHED_RUN_FROM_ENEMY_MOB:
		{
			// Get under cover if we're able to
			if ( ShouldRunToCover() )
				return SCHED_INJURED_RUN_FROM_ENEMY;

			// Run to our follow goal if we're too far away from it
			if ( ShouldRunToFollowGoal() )
				return SCHED_FOLLOW;

			// Cower if surrounded
			if ( HasCondition( COND_INJURED_OVERWHELMED ) )
				return SCHED_INJURED_COWER;

			// Face our enemies
			return SCHED_INJURED_FEAR_FACE;
		}
		break;

	case SCHED_RUN_FROM_ENEMY_FALLBACK:
		return SCHED_INJURED_COWER;
		break;
	}

	return BaseClass::TranslateSchedule( scheduleType );
}