|
|
//========= 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( void ); 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
|