You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
9.0 KiB
297 lines
9.0 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#ifndef NPC_COMBINE_H |
|
#define NPC_COMBINE_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include "ai_basenpc.h" |
|
#include "ai_basehumanoid.h" |
|
#include "ai_behavior.h" |
|
#include "ai_behavior_assault.h" |
|
#include "ai_behavior_standoff.h" |
|
#include "ai_behavior_follow.h" |
|
#include "ai_behavior_functank.h" |
|
#include "ai_behavior_rappel.h" |
|
#include "ai_behavior_actbusy.h" |
|
#include "ai_sentence.h" |
|
#include "ai_baseactor.h" |
|
|
|
// Used when only what combine to react to what the spotlight sees |
|
#define SF_COMBINE_NO_LOOK (1 << 16) |
|
#define SF_COMBINE_NO_GRENADEDROP ( 1 << 17 ) |
|
#define SF_COMBINE_NO_AR2DROP ( 1 << 18 ) |
|
|
|
//========================================================= |
|
// >> CNPC_Combine |
|
//========================================================= |
|
class CNPC_Combine : public CAI_BaseActor |
|
{ |
|
DECLARE_DATADESC(); |
|
DEFINE_CUSTOM_AI; |
|
DECLARE_CLASS( CNPC_Combine, CAI_BaseActor ); |
|
|
|
public: |
|
CNPC_Combine(); |
|
|
|
// Create components |
|
virtual bool CreateComponents(); |
|
|
|
bool CanThrowGrenade( const Vector &vecTarget ); |
|
bool CheckCanThrowGrenade( const Vector &vecTarget ); |
|
virtual bool CanGrenadeEnemy( bool bUseFreeKnowledge = true ); |
|
virtual bool CanAltFireEnemy( bool bUseFreeKnowledge ); |
|
int GetGrenadeConditions( float flDot, float flDist ); |
|
int RangeAttack2Conditions( float flDot, float flDist ); // For innate grenade attack |
|
int MeleeAttack1Conditions( float flDot, float flDist ); // For kick/punch |
|
bool FVisible( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); |
|
virtual bool IsCurTaskContinuousMove(); |
|
|
|
virtual float GetJumpGravity() const { return 1.8f; } |
|
|
|
virtual Vector GetCrouchEyeOffset( void ); |
|
|
|
void Event_Killed( const CTakeDamageInfo &info ); |
|
|
|
|
|
void SetActivity( Activity NewActivity ); |
|
NPC_STATE SelectIdealState ( void ); |
|
|
|
// Input handlers. |
|
void InputLookOn( inputdata_t &inputdata ); |
|
void InputLookOff( inputdata_t &inputdata ); |
|
void InputStartPatrolling( inputdata_t &inputdata ); |
|
void InputStopPatrolling( inputdata_t &inputdata ); |
|
void InputAssault( inputdata_t &inputdata ); |
|
void InputHitByBugbait( inputdata_t &inputdata ); |
|
void InputThrowGrenadeAtTarget( inputdata_t &inputdata ); |
|
|
|
bool UpdateEnemyMemory( CBaseEntity *pEnemy, const Vector &position, CBaseEntity *pInformer = NULL ); |
|
|
|
void Spawn( void ); |
|
void Precache( void ); |
|
void Activate(); |
|
|
|
Class_T Classify( void ); |
|
bool IsElite() { return m_fIsElite; } |
|
void DelayAltFireAttack( float flDelay ); |
|
void DelaySquadAltFireAttack( float flDelay ); |
|
float MaxYawSpeed( void ); |
|
bool ShouldMoveAndShoot(); |
|
bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval );; |
|
void HandleAnimEvent( animevent_t *pEvent ); |
|
Vector Weapon_ShootPosition( ); |
|
|
|
Vector EyeOffset( Activity nActivity ); |
|
Vector EyePosition( void ); |
|
Vector BodyTarget( const Vector &posSrc, bool bNoisy = true ); |
|
Vector GetAltFireTarget(); |
|
|
|
void StartTask( const Task_t *pTask ); |
|
void RunTask( const Task_t *pTask ); |
|
void PostNPCInit(); |
|
void GatherConditions(); |
|
virtual void PrescheduleThink(); |
|
|
|
Activity NPC_TranslateActivity( Activity eNewActivity ); |
|
void BuildScheduleTestBits( void ); |
|
virtual int SelectSchedule( void ); |
|
virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode ); |
|
int SelectScheduleAttack(); |
|
|
|
bool CreateBehaviors(); |
|
|
|
bool OnBeginMoveAndShoot(); |
|
void OnEndMoveAndShoot(); |
|
|
|
// Combat |
|
WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ); |
|
bool HasShotgun(); |
|
bool ActiveWeaponIsFullyLoaded(); |
|
|
|
bool HandleInteraction(int interactionType, void *data, CBaseCombatCharacter *sourceEnt); |
|
const char* GetSquadSlotDebugName( int iSquadSlot ); |
|
|
|
bool IsUsingTacticalVariant( int variant ); |
|
bool IsUsingPathfindingVariant( int variant ) { return m_iPathfindingVariant == variant; } |
|
|
|
bool IsRunningApproachEnemySchedule(); |
|
|
|
// ------------- |
|
// Sounds |
|
// ------------- |
|
void DeathSound( void ); |
|
void PainSound( const CTakeDamageInfo &damageinfo ); |
|
void IdleSound( void ); |
|
void AlertSound( void ); |
|
void LostEnemySound( void ); |
|
void FoundEnemySound( void ); |
|
void AnnounceAssault( void ); |
|
void AnnounceEnemyType( CBaseEntity *pEnemy ); |
|
void AnnounceEnemyKill( CBaseEntity *pEnemy ); |
|
|
|
void NotifyDeadFriend( CBaseEntity* pFriend ); |
|
|
|
virtual float HearingSensitivity( void ) { return 1.0; }; |
|
int GetSoundInterests( void ); |
|
virtual bool QueryHearSound( CSound *pSound ); |
|
|
|
// Speaking |
|
void SpeakSentence( int sentType ); |
|
|
|
virtual int TranslateSchedule( int scheduleType ); |
|
void OnStartSchedule( int scheduleType ); |
|
|
|
virtual bool ShouldPickADeathPose( void ); |
|
|
|
protected: |
|
void SetKickDamage( int nDamage ) { m_nKickDamage = nDamage; } |
|
CAI_Sentence< CNPC_Combine > *GetSentences() { return &m_Sentences; } |
|
|
|
private: |
|
//========================================================= |
|
// Combine S schedules |
|
//========================================================= |
|
enum |
|
{ |
|
SCHED_COMBINE_SUPPRESS = BaseClass::NEXT_SCHEDULE, |
|
SCHED_COMBINE_COMBAT_FAIL, |
|
SCHED_COMBINE_VICTORY_DANCE, |
|
SCHED_COMBINE_COMBAT_FACE, |
|
SCHED_COMBINE_HIDE_AND_RELOAD, |
|
SCHED_COMBINE_SIGNAL_SUPPRESS, |
|
SCHED_COMBINE_ENTER_OVERWATCH, |
|
SCHED_COMBINE_OVERWATCH, |
|
SCHED_COMBINE_ASSAULT, |
|
SCHED_COMBINE_ESTABLISH_LINE_OF_FIRE, |
|
SCHED_COMBINE_PRESS_ATTACK, |
|
SCHED_COMBINE_WAIT_IN_COVER, |
|
SCHED_COMBINE_RANGE_ATTACK1, |
|
SCHED_COMBINE_RANGE_ATTACK2, |
|
SCHED_COMBINE_TAKE_COVER1, |
|
SCHED_COMBINE_TAKE_COVER_FROM_BEST_SOUND, |
|
SCHED_COMBINE_RUN_AWAY_FROM_BEST_SOUND, |
|
SCHED_COMBINE_GRENADE_COVER1, |
|
SCHED_COMBINE_TOSS_GRENADE_COVER1, |
|
SCHED_COMBINE_TAKECOVER_FAILED, |
|
SCHED_COMBINE_GRENADE_AND_RELOAD, |
|
SCHED_COMBINE_PATROL, |
|
SCHED_COMBINE_BUGBAIT_DISTRACTION, |
|
SCHED_COMBINE_CHARGE_TURRET, |
|
SCHED_COMBINE_DROP_GRENADE, |
|
SCHED_COMBINE_CHARGE_PLAYER, |
|
SCHED_COMBINE_PATROL_ENEMY, |
|
SCHED_COMBINE_BURNING_STAND, |
|
SCHED_COMBINE_AR2_ALTFIRE, |
|
SCHED_COMBINE_FORCED_GRENADE_THROW, |
|
SCHED_COMBINE_MOVE_TO_FORCED_GREN_LOS, |
|
SCHED_COMBINE_FACE_IDEAL_YAW, |
|
SCHED_COMBINE_MOVE_TO_MELEE, |
|
NEXT_SCHEDULE, |
|
}; |
|
|
|
//========================================================= |
|
// Combine Tasks |
|
//========================================================= |
|
enum |
|
{ |
|
TASK_COMBINE_FACE_TOSS_DIR = BaseClass::NEXT_TASK, |
|
TASK_COMBINE_IGNORE_ATTACKS, |
|
TASK_COMBINE_SIGNAL_BEST_SOUND, |
|
TASK_COMBINE_DEFER_SQUAD_GRENADES, |
|
TASK_COMBINE_CHASE_ENEMY_CONTINUOUSLY, |
|
TASK_COMBINE_DIE_INSTANTLY, |
|
TASK_COMBINE_PLAY_SEQUENCE_FACE_ALTFIRE_TARGET, |
|
TASK_COMBINE_GET_PATH_TO_FORCED_GREN_LOS, |
|
TASK_COMBINE_SET_STANDING, |
|
NEXT_TASK |
|
}; |
|
|
|
//========================================================= |
|
// Combine Conditions |
|
//========================================================= |
|
enum Combine_Conds |
|
{ |
|
COND_COMBINE_NO_FIRE = BaseClass::NEXT_CONDITION, |
|
COND_COMBINE_DEAD_FRIEND, |
|
COND_COMBINE_SHOULD_PATROL, |
|
COND_COMBINE_HIT_BY_BUGBAIT, |
|
COND_COMBINE_DROP_GRENADE, |
|
COND_COMBINE_ON_FIRE, |
|
COND_COMBINE_ATTACK_SLOT_AVAILABLE, |
|
NEXT_CONDITION |
|
}; |
|
|
|
private: |
|
// Select the combat schedule |
|
int SelectCombatSchedule(); |
|
|
|
// Should we charge the player? |
|
bool ShouldChargePlayer(); |
|
|
|
// Chase the enemy, updating the target position as the player moves |
|
void StartTaskChaseEnemyContinuously( const Task_t *pTask ); |
|
void RunTaskChaseEnemyContinuously( const Task_t *pTask ); |
|
|
|
class CCombineStandoffBehavior : public CAI_ComponentWithOuter<CNPC_Combine, CAI_StandoffBehavior> |
|
{ |
|
typedef CAI_ComponentWithOuter<CNPC_Combine, CAI_StandoffBehavior> BaseClass; |
|
|
|
virtual int SelectScheduleAttack() |
|
{ |
|
int result = GetOuter()->SelectScheduleAttack(); |
|
if ( result == SCHED_NONE ) |
|
result = BaseClass::SelectScheduleAttack(); |
|
return result; |
|
} |
|
}; |
|
|
|
// Rappel |
|
virtual bool IsWaitingToRappel( void ) { return m_RappelBehavior.IsWaitingToRappel(); } |
|
void BeginRappel() { m_RappelBehavior.BeginRappel(); } |
|
|
|
private: |
|
int m_nKickDamage; |
|
Vector m_vecTossVelocity; |
|
EHANDLE m_hForcedGrenadeTarget; |
|
bool m_bShouldPatrol; |
|
bool m_bFirstEncounter;// only put on the handsign show in the squad's first encounter. |
|
|
|
// Time Variables |
|
float m_flNextPainSoundTime; |
|
float m_flNextAlertSoundTime; |
|
float m_flNextGrenadeCheck; |
|
float m_flNextLostSoundTime; |
|
float m_flAlertPatrolTime; // When to stop doing alert patrol |
|
float m_flNextAltFireTime; // Elites only. Next time to begin considering alt-fire attack. |
|
|
|
int m_nShots; |
|
float m_flShotDelay; |
|
float m_flStopMoveShootTime; |
|
|
|
CAI_Sentence< CNPC_Combine > m_Sentences; |
|
|
|
int m_iNumGrenades; |
|
CAI_AssaultBehavior m_AssaultBehavior; |
|
CCombineStandoffBehavior m_StandoffBehavior; |
|
CAI_FollowBehavior m_FollowBehavior; |
|
CAI_FuncTankBehavior m_FuncTankBehavior; |
|
CAI_RappelBehavior m_RappelBehavior; |
|
CAI_ActBusyBehavior m_ActBusyBehavior; |
|
|
|
public: |
|
int m_iLastAnimEventHandled; |
|
bool m_fIsElite; |
|
Vector m_vecAltFireTarget; |
|
|
|
int m_iTacticalVariant; |
|
int m_iPathfindingVariant; |
|
}; |
|
|
|
|
|
#endif // NPC_COMBINE_H
|
|
|