mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 06:36:54 +00:00
298 lines
9.0 KiB
C++
298 lines
9.0 KiB
C++
//========= 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
|