diff options
Diffstat (limited to 'mp/src/game/server/hl2/npc_metropolice.h')
| -rw-r--r-- | mp/src/game/server/hl2/npc_metropolice.h | 940 |
1 files changed, 470 insertions, 470 deletions
diff --git a/mp/src/game/server/hl2/npc_metropolice.h b/mp/src/game/server/hl2/npc_metropolice.h index 55f5006a..544fc68b 100644 --- a/mp/src/game/server/hl2/npc_metropolice.h +++ b/mp/src/game/server/hl2/npc_metropolice.h @@ -1,470 +1,470 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef NPC_METROPOLICE_H
-#define NPC_METROPOLICE_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "rope.h"
-#include "rope_shared.h"
-#include "ai_baseactor.h"
-#include "ai_basenpc.h"
-#include "ai_goal_police.h"
-#include "ai_behavior.h"
-#include "ai_behavior_standoff.h"
-#include "ai_behavior_assault.h"
-#include "ai_behavior_functank.h"
-#include "ai_behavior_actbusy.h"
-#include "ai_behavior_rappel.h"
-#include "ai_behavior_police.h"
-#include "ai_behavior_follow.h"
-#include "ai_sentence.h"
-#include "props.h"
-
-class CNPC_MetroPolice;
-
-class CNPC_MetroPolice : public CAI_BaseActor
-{
- DECLARE_CLASS( CNPC_MetroPolice, CAI_BaseActor );
- DECLARE_DATADESC();
-
-public:
- CNPC_MetroPolice();
-
- virtual bool CreateComponents();
- bool CreateBehaviors();
- void Spawn( void );
- void Precache( void );
-
- Class_T Classify( void );
- Disposition_t IRelationType(CBaseEntity *pTarget);
- float MaxYawSpeed( void );
- void HandleAnimEvent( animevent_t *pEvent );
- Activity NPC_TranslateActivity( Activity newActivity );
-
- Vector EyeDirection3D( void ) { return CAI_BaseHumanoid::EyeDirection3D(); } // cops don't have eyes
-
- virtual void Event_Killed( const CTakeDamageInfo &info );
-
- virtual void OnScheduleChange();
-
- float GetIdealAccel( void ) const;
- int ObjectCaps( void ) { return UsableNPCObjectCaps(BaseClass::ObjectCaps()); }
- void PrecriminalUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
-
- // These are overridden so that the cop can shove and move a non-criminal player safely
- CBaseEntity *CheckTraceHullAttack( float flDist, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float forceScale, bool bDamageAnyNPC );
- CBaseEntity *CheckTraceHullAttack( const Vector &vStart, const Vector &vEnd, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float flForceScale, bool bDamageAnyNPC );
-
- virtual int SelectSchedule( void );
- virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
- virtual int TranslateSchedule( int scheduleType );
- void StartTask( const Task_t *pTask );
- void RunTask( const Task_t *pTask );
- virtual Vector GetActualShootTrajectory( const Vector &shootOrigin );
- virtual void FireBullets( const FireBulletsInfo_t &info );
- virtual bool HandleInteraction(int interactionType, void *data, CBaseCombatCharacter* sourceEnt);
- virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon );
-
- //virtual bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval );
- bool OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult );
- bool ShouldBruteForceFailedNav() { return false; }
-
- virtual void GatherConditions( void );
-
- virtual bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval );
-
- // Can't move and shoot when the enemy is an airboat
- virtual bool ShouldMoveAndShoot();
-
- // TraceAttack
- virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
-
- // Speaking
- virtual void SpeakSentence( int nSentenceType );
-
- // Set up the shot regulator based on the equipped weapon
- virtual void OnUpdateShotRegulator( );
-
- bool ShouldKnockOutTarget( CBaseEntity *pTarget );
- void KnockOutTarget( CBaseEntity *pTarget );
- void StunnedTarget( CBaseEntity *pTarget );
- void AdministerJustice( void );
-
- bool QueryHearSound( CSound *pSound );
-
- void SetBatonState( bool state );
- bool BatonActive( void );
-
- CAI_Sentence< CNPC_MetroPolice > *GetSentences() { return &m_Sentences; }
-
- virtual bool AllowedToIgnite( void ) { return true; }
-
- void PlayFlinchGesture( void );
-
-protected:
- // Determines the best type of flinch anim to play.
- virtual Activity GetFlinchActivity( bool bHeavyDamage, bool bGesture );
-
- // Only move and shoot when attacking
- virtual bool OnBeginMoveAndShoot();
- virtual void OnEndMoveAndShoot();
-
-private:
- bool PlayerIsCriminal( void );
- void ReleaseManhack( void );
-
- // Speech-related methods
- void AnnounceTakeCoverFromDanger( CSound *pSound );
- void AnnounceEnemyType( CBaseEntity *pEnemy );
- void AnnounceEnemyKill( CBaseEntity *pEnemy );
- void AnnounceHarrassment( );
- void AnnounceOutOfAmmo( );
-
- // Behavior-related sentences
- void SpeakFuncTankSentence( int nSentenceType );
- void SpeakAssaultSentence( int nSentenceType );
- void SpeakStandoffSentence( int nSentenceType );
-
- virtual void LostEnemySound( void );
- virtual void FoundEnemySound( void );
- virtual void AlertSound( void );
- virtual void PainSound( const CTakeDamageInfo &info );
- virtual void DeathSound( const CTakeDamageInfo &info );
- virtual void IdleSound( void );
- virtual bool ShouldPlayIdleSound( void );
-
- // Burst mode!
- void SetBurstMode( bool bEnable );
-
- int OnTakeDamage_Alive( const CTakeDamageInfo &info );
-
- int GetSoundInterests( void );
-
- void BuildScheduleTestBits( void );
-
- bool CanDeployManhack( void );
-
- bool ShouldHitPlayer( const Vector &targetDir, float targetDist );
-
- void PrescheduleThink( void );
-
- void SetPlayerCriminalDuration( float time );
-
- void IncrementPlayerCriminalStatus( void );
-
- virtual bool UseAttackSquadSlots() { return true; }
-
- WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon );
-
- // Inputs
- void InputEnableManhackToss( inputdata_t &inputdata );
- void InputSetPoliceGoal( inputdata_t &inputdata );
- void InputActivateBaton( inputdata_t &inputdata );
-
- void NotifyDeadFriend ( CBaseEntity* pFriend );
-
- // Stitch aiming!
- void AimBurstRandomly( int nMinCount, int nMaxCount, float flMinDelay, float flMaxDelay );
- void AimBurstAtEnemy( float flReactionTime );
- void AimBurstInFrontOfEnemy( float flReactionTime );
- void AimBurstAlongSideOfEnemy( float flFollowTime );
- void AimBurstBehindEnemy( float flFollowTime );
- void AimBurstTightGrouping( float flShotTime );
-
- // Anim event handlers
- void OnAnimEventDeployManhack( animevent_t *pEvent );
- void OnAnimEventShove( void );
- void OnAnimEventBatonOn( void );
- void OnAnimEventBatonOff( void );
- void OnAnimEventStartDeployManhack( void );
- void OnAnimEventPreDeployManhack( void );
-
- bool HasBaton( void );
-
- // Normal schedule selection
- int SelectCombatSchedule();
- int SelectScheduleNewEnemy();
- int SelectScheduleArrestEnemy();
- int SelectRangeAttackSchedule();
- int SelectScheduleNoDirectEnemy();
- int SelectScheduleInvestigateSound();
- int SelectShoveSchedule( void );
-
- bool TryToEnterPistolSlot( int nSquadSlot );
-
- // Airboat schedule selection
- int SelectAirboatCombatSchedule();
- int SelectAirboatRangeAttackSchedule();
-
- // Handle flinching
- bool IsHeavyDamage( const CTakeDamageInfo &info );
-
- // Is my enemy currently in an airboat?
- bool IsEnemyInAnAirboat() const;
-
- // Returns the airboat
- CBaseEntity *GetEnemyAirboat() const;
-
- // Compute a predicted enemy position n seconds into the future
- void PredictShootTargetPosition( float flDeltaTime, float flMinLeadDist, float flAddVelocity, Vector *pVecTarget, Vector *pVecTargetVel );
-
- // Compute a predicted velocity n seconds into the future (given a known acceleration rate)
- void PredictShootTargetVelocity( float flDeltaTime, Vector *pVecTargetVel );
-
- // How many shots will I fire in a particular amount of time?
- int CountShotsInTime( float flDeltaTime ) const;
- float GetTimeForShots( int nShotCount ) const;
-
- // Visualize stitch
- void VisualizeStitch( const Vector &vecStart, const Vector &vecEnd );
-
- // Visualize line of death
- void VisualizeLineOfDeath( );
-
- // Modify the stitch length
- float ComputeDistanceStitchModifier( float flDistanceToTarget ) const;
-
- // Adjusts the burst toward the target as it's being fired.
- void SteerBurstTowardTarget( );
-
- // Methods to compute shot trajectory based on burst mode
- Vector ComputeBurstLockOnTrajectory( const Vector &shootOrigin );
- Vector ComputeBurstDeliberatelyMissTrajectory( const Vector &shootOrigin );
- Vector ComputeBurstTrajectory( const Vector &shootOrigin );
- Vector ComputeTightBurstTrajectory( const Vector &shootOrigin );
-
- // Are we currently firing a burst?
- bool IsCurrentlyFiringBurst() const;
-
- // Which entity are we actually trying to shoot at?
- CBaseEntity *GetShootTarget();
-
- // Different burst steering modes
- void SteerBurstTowardTargetUseSpeedOnly( const Vector &vecShootAt, const Vector &vecShootAtVelocity, float flPredictTime, int nShotsTillPredict );
- void SteerBurstTowardTargetUseVelocity( const Vector &vecShootAt, const Vector &vecShootAtVelocity, int nShotsTillPredict );
- void SteerBurstTowardTargetUsePosition( const Vector &vecShootAt, const Vector &vecShootAtVelocity, int nShotsTillPredict );
- void SteerBurstTowardPredictedPoint( const Vector &vecShootAt, const Vector &vecShootAtVelocity, int nShotsTillPredict );
- void SteerBurstWithinLineOfDeath( );
-
- // Set up the shot regulator
- int SetupBurstShotRegulator( float flReactionTime );
-
- // Choose a random vector somewhere between the two specified vectors
- void RandomDirectionBetweenVectors( const Vector &vecStart, const Vector &vecEnd, Vector *pResult );
-
- // Stitch selector
- float StitchAtWeight( float flDist, float flSpeed, float flDot, float flReactionTime, const Vector &vecTargetToGun );
- float StitchAcrossWeight( float flDist, float flSpeed, float flDot, float flReactionTime );
- float StitchAlongSideWeight( float flDist, float flSpeed, float flDot );
- float StitchBehindWeight( float flDist, float flSpeed, float flDot );
- float StitchTightWeight( float flDist, float flSpeed, const Vector &vecTargetToGun, const Vector &vecVelocity );
- int SelectStitchSchedule();
-
- // Can me enemy see me?
- bool CanEnemySeeMe( );
-
- // Combat schedule selection
- int SelectMoveToLedgeSchedule();
-
- // position to shoot at
- Vector StitchAimTarget( const Vector &posSrc, bool bNoisy );
-
- // Should we attempt to stitch?
- bool ShouldAttemptToStitch();
-
- // Deliberately aims as close as possible w/o hitting
- Vector AimCloseToTargetButMiss( CBaseEntity *pTarget, const Vector &shootOrigin );
-
- // Compute the actual reaction time based on distance + speed modifiers
- float AimBurstAtReactionTime( float flReactonTime, float flDistToTargetSqr, float flCurrentSpeed );
- int AimBurstAtSetupHitCount( float flDistToTargetSqr, float flCurrentSpeed );
-
- // How many squad members are trying to arrest the player?
- int SquadArrestCount();
-
- // He's resisting arrest!
- void EnemyResistingArrest();
- void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
-
- // Rappel
- virtual bool IsWaitingToRappel( void ) { return m_RappelBehavior.IsWaitingToRappel(); }
- void BeginRappel() { m_RappelBehavior.BeginRappel(); }
-
-private:
- enum
- {
- BURST_NOT_ACTIVE = 0,
- BURST_ACTIVE,
- BURST_LOCK_ON_AFTER_HIT,
- BURST_LOCKED_ON,
- BURST_DELIBERATELY_MISS,
- BURST_TIGHT_GROUPING,
- };
-
- enum
- {
- BURST_STEER_NONE = 0,
- BURST_STEER_TOWARD_PREDICTED_POINT,
- BURST_STEER_WITHIN_LINE_OF_DEATH,
- BURST_STEER_ADJUST_FOR_SPEED_CHANGES,
- BURST_STEER_EXACTLY_TOWARD_TARGET,
- };
-
- enum
- {
- COND_METROPOLICE_ON_FIRE = BaseClass::NEXT_CONDITION,
- COND_METROPOLICE_ENEMY_RESISTING_ARREST,
- COND_METROPOLICE_PLAYER_TOO_CLOSE,
- COND_METROPOLICE_CHANGE_BATON_STATE,
- COND_METROPOLICE_PHYSOBJECT_ASSAULT,
-
- };
-
- enum
- {
- SCHED_METROPOLICE_WALK = BaseClass::NEXT_SCHEDULE,
- SCHED_METROPOLICE_WAKE_ANGRY,
- SCHED_METROPOLICE_HARASS,
- SCHED_METROPOLICE_CHASE_ENEMY,
- SCHED_METROPOLICE_ESTABLISH_LINE_OF_FIRE,
- SCHED_METROPOLICE_DRAW_PISTOL,
- SCHED_METROPOLICE_DEPLOY_MANHACK,
- SCHED_METROPOLICE_ADVANCE,
- SCHED_METROPOLICE_CHARGE,
- SCHED_METROPOLICE_BURNING_RUN,
- SCHED_METROPOLICE_BURNING_STAND,
- SCHED_METROPOLICE_SMG_NORMAL_ATTACK,
- SCHED_METROPOLICE_SMG_BURST_ATTACK,
- SCHED_METROPOLICE_AIM_STITCH_AT_AIRBOAT,
- SCHED_METROPOLICE_AIM_STITCH_IN_FRONT_OF_AIRBOAT,
- SCHED_METROPOLICE_AIM_STITCH_TIGHTLY,
- SCHED_METROPOLICE_AIM_STITCH_ALONG_SIDE_OF_AIRBOAT,
- SCHED_METROPOLICE_AIM_STITCH_BEHIND_AIRBOAT,
- SCHED_METROPOLICE_ESTABLISH_STITCH_LINE_OF_FIRE,
- SCHED_METROPOLICE_INVESTIGATE_SOUND,
- SCHED_METROPOLICE_WARN_AND_ARREST_ENEMY,
- SCHED_METROPOLICE_ARREST_ENEMY,
- SCHED_METROPOLICE_ENEMY_RESISTING_ARREST,
- SCHED_METROPOLICE_WARN_TARGET,
- SCHED_METROPOLICE_HARASS_TARGET,
- SCHED_METROPOLICE_SUPPRESS_TARGET,
- SCHED_METROPOLICE_RETURN_FROM_HARASS,
- SCHED_METROPOLICE_SHOVE,
- SCHED_METROPOLICE_ACTIVATE_BATON,
- SCHED_METROPOLICE_DEACTIVATE_BATON,
- SCHED_METROPOLICE_ALERT_FACE_BESTSOUND,
- SCHED_METROPOLICE_RETURN_TO_PRECHASE,
- SCHED_METROPOLICE_SMASH_PROP,
- };
-
- enum
- {
- TASK_METROPOLICE_HARASS = BaseClass::NEXT_TASK,
- TASK_METROPOLICE_DIE_INSTANTLY,
- TASK_METROPOLICE_BURST_ATTACK,
- TASK_METROPOLICE_STOP_FIRE_BURST,
- TASK_METROPOLICE_AIM_STITCH_AT_PLAYER,
- TASK_METROPOLICE_AIM_STITCH_AT_AIRBOAT,
- TASK_METROPOLICE_AIM_STITCH_TIGHTLY,
- TASK_METROPOLICE_AIM_STITCH_IN_FRONT_OF_AIRBOAT,
- TASK_METROPOLICE_AIM_STITCH_ALONG_SIDE_OF_AIRBOAT,
- TASK_METROPOLICE_AIM_STITCH_BEHIND_AIRBOAT,
- TASK_METROPOLICE_RELOAD_FOR_BURST,
- TASK_METROPOLICE_GET_PATH_TO_STITCH,
- TASK_METROPOLICE_RESET_LEDGE_CHECK_TIME,
- TASK_METROPOLICE_GET_PATH_TO_BESTSOUND_LOS,
- TASK_METROPOLICE_AIM_WEAPON_AT_ENEMY,
- TASK_METROPOLICE_ARREST_ENEMY,
- TASK_METROPOLICE_LEAD_ARREST_ENEMY,
- TASK_METROPOLICE_SIGNAL_FIRING_TIME,
- TASK_METROPOLICE_ACTIVATE_BATON,
- TASK_METROPOLICE_WAIT_FOR_SENTENCE,
- TASK_METROPOLICE_GET_PATH_TO_PRECHASE,
- TASK_METROPOLICE_CLEAR_PRECHASE,
- };
-
-private:
-
- int m_iPistolClips; // How many clips the cop has in reserve
- int m_iManhacks; // How many manhacks the cop has
- bool m_fWeaponDrawn; // Is my weapon drawn? (ready to use)
- bool m_bSimpleCops; // The easy version of the cops
- int m_LastShootSlot;
- CRandSimTimer m_TimeYieldShootSlot;
- CSimpleSimTimer m_BatonSwingTimer;
- CSimpleSimTimer m_NextChargeTimer;
-
- // All related to burst firing
- Vector m_vecBurstTargetPos;
- Vector m_vecBurstDelta;
- int m_nBurstHits;
- int m_nMaxBurstHits;
- int m_nBurstReloadCount;
- Vector m_vecBurstLineOfDeathDelta;
- Vector m_vecBurstLineOfDeathOrigin;
- int m_nBurstMode;
- int m_nBurstSteerMode;
- float m_flBurstSteerDistance;
- float m_flBurstPredictTime;
- Vector m_vecBurstPredictedVelocityDir;
- float m_vecBurstPredictedSpeed;
- float m_flValidStitchTime;
- float m_flNextLedgeCheckTime;
- float m_flTaskCompletionTime;
-
- bool m_bShouldActivateBaton;
- float m_flBatonDebounceTime; // Minimum amount of time before turning the baton off
- float m_flLastPhysicsFlinchTime;
- float m_flLastDamageFlinchTime;
-
- // Sentences
- float m_flNextPainSoundTime;
- float m_flNextLostSoundTime;
- int m_nIdleChatterType;
- bool m_bPlayerIsNear;
-
- // Policing state
- bool m_bPlayerTooClose;
- bool m_bKeepFacingPlayer;
- float m_flChasePlayerTime;
- Vector m_vecPreChaseOrigin;
- float m_flPreChaseYaw;
- int m_nNumWarnings;
- int m_iNumPlayerHits;
-
- // Outputs
- COutputEvent m_OnStunnedPlayer;
- COutputEvent m_OnCupCopped;
-
- AIHANDLE m_hManhack;
- CHandle<CPhysicsProp> m_hBlockingProp;
-
- CAI_ActBusyBehavior m_ActBusyBehavior;
- CAI_StandoffBehavior m_StandoffBehavior;
- CAI_AssaultBehavior m_AssaultBehavior;
- CAI_FuncTankBehavior m_FuncTankBehavior;
- CAI_RappelBehavior m_RappelBehavior;
- CAI_PolicingBehavior m_PolicingBehavior;
- CAI_FollowBehavior m_FollowBehavior;
-
- CAI_Sentence< CNPC_MetroPolice > m_Sentences;
-
- int m_nRecentDamage;
- float m_flRecentDamageTime;
-
- // The last hit direction, measured as a yaw relative to our orientation
- float m_flLastHitYaw;
-
- static float gm_flTimeLastSpokePeek;
-
-public:
- DEFINE_CUSTOM_AI;
-};
-
-#endif // NPC_METROPOLICE_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef NPC_METROPOLICE_H +#define NPC_METROPOLICE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "rope.h" +#include "rope_shared.h" +#include "ai_baseactor.h" +#include "ai_basenpc.h" +#include "ai_goal_police.h" +#include "ai_behavior.h" +#include "ai_behavior_standoff.h" +#include "ai_behavior_assault.h" +#include "ai_behavior_functank.h" +#include "ai_behavior_actbusy.h" +#include "ai_behavior_rappel.h" +#include "ai_behavior_police.h" +#include "ai_behavior_follow.h" +#include "ai_sentence.h" +#include "props.h" + +class CNPC_MetroPolice; + +class CNPC_MetroPolice : public CAI_BaseActor +{ + DECLARE_CLASS( CNPC_MetroPolice, CAI_BaseActor ); + DECLARE_DATADESC(); + +public: + CNPC_MetroPolice(); + + virtual bool CreateComponents(); + bool CreateBehaviors(); + void Spawn( void ); + void Precache( void ); + + Class_T Classify( void ); + Disposition_t IRelationType(CBaseEntity *pTarget); + float MaxYawSpeed( void ); + void HandleAnimEvent( animevent_t *pEvent ); + Activity NPC_TranslateActivity( Activity newActivity ); + + Vector EyeDirection3D( void ) { return CAI_BaseHumanoid::EyeDirection3D(); } // cops don't have eyes + + virtual void Event_Killed( const CTakeDamageInfo &info ); + + virtual void OnScheduleChange(); + + float GetIdealAccel( void ) const; + int ObjectCaps( void ) { return UsableNPCObjectCaps(BaseClass::ObjectCaps()); } + void PrecriminalUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + + // These are overridden so that the cop can shove and move a non-criminal player safely + CBaseEntity *CheckTraceHullAttack( float flDist, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float forceScale, bool bDamageAnyNPC ); + CBaseEntity *CheckTraceHullAttack( const Vector &vStart, const Vector &vEnd, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float flForceScale, bool bDamageAnyNPC ); + + virtual int SelectSchedule( void ); + virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode ); + virtual int TranslateSchedule( int scheduleType ); + void StartTask( const Task_t *pTask ); + void RunTask( const Task_t *pTask ); + virtual Vector GetActualShootTrajectory( const Vector &shootOrigin ); + virtual void FireBullets( const FireBulletsInfo_t &info ); + virtual bool HandleInteraction(int interactionType, void *data, CBaseCombatCharacter* sourceEnt); + virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon ); + + //virtual bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval ); + bool OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ); + bool ShouldBruteForceFailedNav() { return false; } + + virtual void GatherConditions( void ); + + virtual bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval ); + + // Can't move and shoot when the enemy is an airboat + virtual bool ShouldMoveAndShoot(); + + // TraceAttack + virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ); + + // Speaking + virtual void SpeakSentence( int nSentenceType ); + + // Set up the shot regulator based on the equipped weapon + virtual void OnUpdateShotRegulator( ); + + bool ShouldKnockOutTarget( CBaseEntity *pTarget ); + void KnockOutTarget( CBaseEntity *pTarget ); + void StunnedTarget( CBaseEntity *pTarget ); + void AdministerJustice( void ); + + bool QueryHearSound( CSound *pSound ); + + void SetBatonState( bool state ); + bool BatonActive( void ); + + CAI_Sentence< CNPC_MetroPolice > *GetSentences() { return &m_Sentences; } + + virtual bool AllowedToIgnite( void ) { return true; } + + void PlayFlinchGesture( void ); + +protected: + // Determines the best type of flinch anim to play. + virtual Activity GetFlinchActivity( bool bHeavyDamage, bool bGesture ); + + // Only move and shoot when attacking + virtual bool OnBeginMoveAndShoot(); + virtual void OnEndMoveAndShoot(); + +private: + bool PlayerIsCriminal( void ); + void ReleaseManhack( void ); + + // Speech-related methods + void AnnounceTakeCoverFromDanger( CSound *pSound ); + void AnnounceEnemyType( CBaseEntity *pEnemy ); + void AnnounceEnemyKill( CBaseEntity *pEnemy ); + void AnnounceHarrassment( ); + void AnnounceOutOfAmmo( ); + + // Behavior-related sentences + void SpeakFuncTankSentence( int nSentenceType ); + void SpeakAssaultSentence( int nSentenceType ); + void SpeakStandoffSentence( int nSentenceType ); + + virtual void LostEnemySound( void ); + virtual void FoundEnemySound( void ); + virtual void AlertSound( void ); + virtual void PainSound( const CTakeDamageInfo &info ); + virtual void DeathSound( const CTakeDamageInfo &info ); + virtual void IdleSound( void ); + virtual bool ShouldPlayIdleSound( void ); + + // Burst mode! + void SetBurstMode( bool bEnable ); + + int OnTakeDamage_Alive( const CTakeDamageInfo &info ); + + int GetSoundInterests( void ); + + void BuildScheduleTestBits( void ); + + bool CanDeployManhack( void ); + + bool ShouldHitPlayer( const Vector &targetDir, float targetDist ); + + void PrescheduleThink( void ); + + void SetPlayerCriminalDuration( float time ); + + void IncrementPlayerCriminalStatus( void ); + + virtual bool UseAttackSquadSlots() { return true; } + + WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ); + + // Inputs + void InputEnableManhackToss( inputdata_t &inputdata ); + void InputSetPoliceGoal( inputdata_t &inputdata ); + void InputActivateBaton( inputdata_t &inputdata ); + + void NotifyDeadFriend ( CBaseEntity* pFriend ); + + // Stitch aiming! + void AimBurstRandomly( int nMinCount, int nMaxCount, float flMinDelay, float flMaxDelay ); + void AimBurstAtEnemy( float flReactionTime ); + void AimBurstInFrontOfEnemy( float flReactionTime ); + void AimBurstAlongSideOfEnemy( float flFollowTime ); + void AimBurstBehindEnemy( float flFollowTime ); + void AimBurstTightGrouping( float flShotTime ); + + // Anim event handlers + void OnAnimEventDeployManhack( animevent_t *pEvent ); + void OnAnimEventShove( void ); + void OnAnimEventBatonOn( void ); + void OnAnimEventBatonOff( void ); + void OnAnimEventStartDeployManhack( void ); + void OnAnimEventPreDeployManhack( void ); + + bool HasBaton( void ); + + // Normal schedule selection + int SelectCombatSchedule(); + int SelectScheduleNewEnemy(); + int SelectScheduleArrestEnemy(); + int SelectRangeAttackSchedule(); + int SelectScheduleNoDirectEnemy(); + int SelectScheduleInvestigateSound(); + int SelectShoveSchedule( void ); + + bool TryToEnterPistolSlot( int nSquadSlot ); + + // Airboat schedule selection + int SelectAirboatCombatSchedule(); + int SelectAirboatRangeAttackSchedule(); + + // Handle flinching + bool IsHeavyDamage( const CTakeDamageInfo &info ); + + // Is my enemy currently in an airboat? + bool IsEnemyInAnAirboat() const; + + // Returns the airboat + CBaseEntity *GetEnemyAirboat() const; + + // Compute a predicted enemy position n seconds into the future + void PredictShootTargetPosition( float flDeltaTime, float flMinLeadDist, float flAddVelocity, Vector *pVecTarget, Vector *pVecTargetVel ); + + // Compute a predicted velocity n seconds into the future (given a known acceleration rate) + void PredictShootTargetVelocity( float flDeltaTime, Vector *pVecTargetVel ); + + // How many shots will I fire in a particular amount of time? + int CountShotsInTime( float flDeltaTime ) const; + float GetTimeForShots( int nShotCount ) const; + + // Visualize stitch + void VisualizeStitch( const Vector &vecStart, const Vector &vecEnd ); + + // Visualize line of death + void VisualizeLineOfDeath( ); + + // Modify the stitch length + float ComputeDistanceStitchModifier( float flDistanceToTarget ) const; + + // Adjusts the burst toward the target as it's being fired. + void SteerBurstTowardTarget( ); + + // Methods to compute shot trajectory based on burst mode + Vector ComputeBurstLockOnTrajectory( const Vector &shootOrigin ); + Vector ComputeBurstDeliberatelyMissTrajectory( const Vector &shootOrigin ); + Vector ComputeBurstTrajectory( const Vector &shootOrigin ); + Vector ComputeTightBurstTrajectory( const Vector &shootOrigin ); + + // Are we currently firing a burst? + bool IsCurrentlyFiringBurst() const; + + // Which entity are we actually trying to shoot at? + CBaseEntity *GetShootTarget(); + + // Different burst steering modes + void SteerBurstTowardTargetUseSpeedOnly( const Vector &vecShootAt, const Vector &vecShootAtVelocity, float flPredictTime, int nShotsTillPredict ); + void SteerBurstTowardTargetUseVelocity( const Vector &vecShootAt, const Vector &vecShootAtVelocity, int nShotsTillPredict ); + void SteerBurstTowardTargetUsePosition( const Vector &vecShootAt, const Vector &vecShootAtVelocity, int nShotsTillPredict ); + void SteerBurstTowardPredictedPoint( const Vector &vecShootAt, const Vector &vecShootAtVelocity, int nShotsTillPredict ); + void SteerBurstWithinLineOfDeath( ); + + // Set up the shot regulator + int SetupBurstShotRegulator( float flReactionTime ); + + // Choose a random vector somewhere between the two specified vectors + void RandomDirectionBetweenVectors( const Vector &vecStart, const Vector &vecEnd, Vector *pResult ); + + // Stitch selector + float StitchAtWeight( float flDist, float flSpeed, float flDot, float flReactionTime, const Vector &vecTargetToGun ); + float StitchAcrossWeight( float flDist, float flSpeed, float flDot, float flReactionTime ); + float StitchAlongSideWeight( float flDist, float flSpeed, float flDot ); + float StitchBehindWeight( float flDist, float flSpeed, float flDot ); + float StitchTightWeight( float flDist, float flSpeed, const Vector &vecTargetToGun, const Vector &vecVelocity ); + int SelectStitchSchedule(); + + // Can me enemy see me? + bool CanEnemySeeMe( ); + + // Combat schedule selection + int SelectMoveToLedgeSchedule(); + + // position to shoot at + Vector StitchAimTarget( const Vector &posSrc, bool bNoisy ); + + // Should we attempt to stitch? + bool ShouldAttemptToStitch(); + + // Deliberately aims as close as possible w/o hitting + Vector AimCloseToTargetButMiss( CBaseEntity *pTarget, const Vector &shootOrigin ); + + // Compute the actual reaction time based on distance + speed modifiers + float AimBurstAtReactionTime( float flReactonTime, float flDistToTargetSqr, float flCurrentSpeed ); + int AimBurstAtSetupHitCount( float flDistToTargetSqr, float flCurrentSpeed ); + + // How many squad members are trying to arrest the player? + int SquadArrestCount(); + + // He's resisting arrest! + void EnemyResistingArrest(); + void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ); + + // Rappel + virtual bool IsWaitingToRappel( void ) { return m_RappelBehavior.IsWaitingToRappel(); } + void BeginRappel() { m_RappelBehavior.BeginRappel(); } + +private: + enum + { + BURST_NOT_ACTIVE = 0, + BURST_ACTIVE, + BURST_LOCK_ON_AFTER_HIT, + BURST_LOCKED_ON, + BURST_DELIBERATELY_MISS, + BURST_TIGHT_GROUPING, + }; + + enum + { + BURST_STEER_NONE = 0, + BURST_STEER_TOWARD_PREDICTED_POINT, + BURST_STEER_WITHIN_LINE_OF_DEATH, + BURST_STEER_ADJUST_FOR_SPEED_CHANGES, + BURST_STEER_EXACTLY_TOWARD_TARGET, + }; + + enum + { + COND_METROPOLICE_ON_FIRE = BaseClass::NEXT_CONDITION, + COND_METROPOLICE_ENEMY_RESISTING_ARREST, + COND_METROPOLICE_PLAYER_TOO_CLOSE, + COND_METROPOLICE_CHANGE_BATON_STATE, + COND_METROPOLICE_PHYSOBJECT_ASSAULT, + + }; + + enum + { + SCHED_METROPOLICE_WALK = BaseClass::NEXT_SCHEDULE, + SCHED_METROPOLICE_WAKE_ANGRY, + SCHED_METROPOLICE_HARASS, + SCHED_METROPOLICE_CHASE_ENEMY, + SCHED_METROPOLICE_ESTABLISH_LINE_OF_FIRE, + SCHED_METROPOLICE_DRAW_PISTOL, + SCHED_METROPOLICE_DEPLOY_MANHACK, + SCHED_METROPOLICE_ADVANCE, + SCHED_METROPOLICE_CHARGE, + SCHED_METROPOLICE_BURNING_RUN, + SCHED_METROPOLICE_BURNING_STAND, + SCHED_METROPOLICE_SMG_NORMAL_ATTACK, + SCHED_METROPOLICE_SMG_BURST_ATTACK, + SCHED_METROPOLICE_AIM_STITCH_AT_AIRBOAT, + SCHED_METROPOLICE_AIM_STITCH_IN_FRONT_OF_AIRBOAT, + SCHED_METROPOLICE_AIM_STITCH_TIGHTLY, + SCHED_METROPOLICE_AIM_STITCH_ALONG_SIDE_OF_AIRBOAT, + SCHED_METROPOLICE_AIM_STITCH_BEHIND_AIRBOAT, + SCHED_METROPOLICE_ESTABLISH_STITCH_LINE_OF_FIRE, + SCHED_METROPOLICE_INVESTIGATE_SOUND, + SCHED_METROPOLICE_WARN_AND_ARREST_ENEMY, + SCHED_METROPOLICE_ARREST_ENEMY, + SCHED_METROPOLICE_ENEMY_RESISTING_ARREST, + SCHED_METROPOLICE_WARN_TARGET, + SCHED_METROPOLICE_HARASS_TARGET, + SCHED_METROPOLICE_SUPPRESS_TARGET, + SCHED_METROPOLICE_RETURN_FROM_HARASS, + SCHED_METROPOLICE_SHOVE, + SCHED_METROPOLICE_ACTIVATE_BATON, + SCHED_METROPOLICE_DEACTIVATE_BATON, + SCHED_METROPOLICE_ALERT_FACE_BESTSOUND, + SCHED_METROPOLICE_RETURN_TO_PRECHASE, + SCHED_METROPOLICE_SMASH_PROP, + }; + + enum + { + TASK_METROPOLICE_HARASS = BaseClass::NEXT_TASK, + TASK_METROPOLICE_DIE_INSTANTLY, + TASK_METROPOLICE_BURST_ATTACK, + TASK_METROPOLICE_STOP_FIRE_BURST, + TASK_METROPOLICE_AIM_STITCH_AT_PLAYER, + TASK_METROPOLICE_AIM_STITCH_AT_AIRBOAT, + TASK_METROPOLICE_AIM_STITCH_TIGHTLY, + TASK_METROPOLICE_AIM_STITCH_IN_FRONT_OF_AIRBOAT, + TASK_METROPOLICE_AIM_STITCH_ALONG_SIDE_OF_AIRBOAT, + TASK_METROPOLICE_AIM_STITCH_BEHIND_AIRBOAT, + TASK_METROPOLICE_RELOAD_FOR_BURST, + TASK_METROPOLICE_GET_PATH_TO_STITCH, + TASK_METROPOLICE_RESET_LEDGE_CHECK_TIME, + TASK_METROPOLICE_GET_PATH_TO_BESTSOUND_LOS, + TASK_METROPOLICE_AIM_WEAPON_AT_ENEMY, + TASK_METROPOLICE_ARREST_ENEMY, + TASK_METROPOLICE_LEAD_ARREST_ENEMY, + TASK_METROPOLICE_SIGNAL_FIRING_TIME, + TASK_METROPOLICE_ACTIVATE_BATON, + TASK_METROPOLICE_WAIT_FOR_SENTENCE, + TASK_METROPOLICE_GET_PATH_TO_PRECHASE, + TASK_METROPOLICE_CLEAR_PRECHASE, + }; + +private: + + int m_iPistolClips; // How many clips the cop has in reserve + int m_iManhacks; // How many manhacks the cop has + bool m_fWeaponDrawn; // Is my weapon drawn? (ready to use) + bool m_bSimpleCops; // The easy version of the cops + int m_LastShootSlot; + CRandSimTimer m_TimeYieldShootSlot; + CSimpleSimTimer m_BatonSwingTimer; + CSimpleSimTimer m_NextChargeTimer; + + // All related to burst firing + Vector m_vecBurstTargetPos; + Vector m_vecBurstDelta; + int m_nBurstHits; + int m_nMaxBurstHits; + int m_nBurstReloadCount; + Vector m_vecBurstLineOfDeathDelta; + Vector m_vecBurstLineOfDeathOrigin; + int m_nBurstMode; + int m_nBurstSteerMode; + float m_flBurstSteerDistance; + float m_flBurstPredictTime; + Vector m_vecBurstPredictedVelocityDir; + float m_vecBurstPredictedSpeed; + float m_flValidStitchTime; + float m_flNextLedgeCheckTime; + float m_flTaskCompletionTime; + + bool m_bShouldActivateBaton; + float m_flBatonDebounceTime; // Minimum amount of time before turning the baton off + float m_flLastPhysicsFlinchTime; + float m_flLastDamageFlinchTime; + + // Sentences + float m_flNextPainSoundTime; + float m_flNextLostSoundTime; + int m_nIdleChatterType; + bool m_bPlayerIsNear; + + // Policing state + bool m_bPlayerTooClose; + bool m_bKeepFacingPlayer; + float m_flChasePlayerTime; + Vector m_vecPreChaseOrigin; + float m_flPreChaseYaw; + int m_nNumWarnings; + int m_iNumPlayerHits; + + // Outputs + COutputEvent m_OnStunnedPlayer; + COutputEvent m_OnCupCopped; + + AIHANDLE m_hManhack; + CHandle<CPhysicsProp> m_hBlockingProp; + + CAI_ActBusyBehavior m_ActBusyBehavior; + CAI_StandoffBehavior m_StandoffBehavior; + CAI_AssaultBehavior m_AssaultBehavior; + CAI_FuncTankBehavior m_FuncTankBehavior; + CAI_RappelBehavior m_RappelBehavior; + CAI_PolicingBehavior m_PolicingBehavior; + CAI_FollowBehavior m_FollowBehavior; + + CAI_Sentence< CNPC_MetroPolice > m_Sentences; + + int m_nRecentDamage; + float m_flRecentDamageTime; + + // The last hit direction, measured as a yaw relative to our orientation + float m_flLastHitYaw; + + static float gm_flTimeLastSpokePeek; + +public: + DEFINE_CUSTOM_AI; +}; + +#endif // NPC_METROPOLICE_H |