|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef NPC_BASESCANNER_H
#define NPC_BASESCANNER_H
#ifdef _WIN32
#pragma once
#endif
#include "cbase.h"
#include "player_pickup.h"
#include "weapon_physcannon.h"
#include "hl2_player.h"
#include "smoke_trail.h"
#include "ai_basenpc_physicsflyer.h"
//-----------------------------------------------------------------------------
// States for the scanner's sound.
//-----------------------------------------------------------------------------
enum ScannerFlyMode_t { SCANNER_FLY_PHOTO = 0, // Fly close to photograph entity
SCANNER_FLY_PATROL, // Fly slowly around the enviroment
SCANNER_FLY_FAST, // Fly quickly around the enviroment
SCANNER_FLY_CHASE, // Fly quickly around the enviroment
SCANNER_FLY_SPOT, // Fly above enity in spotlight position
SCANNER_FLY_ATTACK, // Get in my enemies face for spray or flash
SCANNER_FLY_DIVE, // Divebomb - only done when dead
SCANNER_FLY_FOLLOW, // Following a target
};
enum ScannerInspectAct_t { SCANNER_INSACT_HANDS_UP, SCANNER_INSACT_SHOWARMBAND, };
// Sentences
#define SCANNER_SENTENCE_ATTENTION 0
#define SCANNER_SENTENCE_HANDSUP 1
#define SCANNER_SENTENCE_PROCEED 2
#define SCANNER_SENTENCE_CURIOUS 3
// Scanner attack distances
#define SCANNER_ATTACK_NEAR_DIST 150 // Fly attack min distance
#define SCANNER_ATTACK_FAR_DIST 300 // Fly attack max distance
#define SCANNER_ATTACK_RANGE 350 // Attack max distance
#define SCANNER_ATTACK_MIN_DELAY 8 // Min time between attacks
#define SCANNER_ATTACK_MAX_DELAY 12 // Max time between attacks
#define SCANNER_EVADE_TIME 1 // How long to evade after take damage
// Scanner movement vars
#define SCANNER_BANK_RATE 30
#define SCANNER_MAX_SPEED 250
#define SCANNER_MAX_DIVE_BOMB_SPEED 2500
#define SCANNER_SQUAD_FLY_DIST 500 // How far to scanners stay apart
#define SCANNER_SQUAD_HELP_DIST 4000 // How far will I fly to help
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CNPC_BaseScanner : public CAI_BasePhysicsFlyingBot, public CDefaultPlayerPickupVPhysics { DECLARE_CLASS( CNPC_BaseScanner, CAI_BasePhysicsFlyingBot );
public: CNPC_BaseScanner();
void Spawn(void);
virtual void UpdateEfficiency( bool bInPVS );
Class_T Classify( void ) { return(CLASS_SCANNER); } virtual float GetAutoAimRadius();
void Event_Killed( const CTakeDamageInfo &info ); int OnTakeDamage_Alive( const CTakeDamageInfo &info ); int OnTakeDamage_Dying( const CTakeDamageInfo &info ); void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ); void Gib(void);
void OnStateChange( NPC_STATE eOldState, NPC_STATE eNewState ); void ClampMotorForces( Vector &linear, AngularImpulse &angular );
int DrawDebugTextOverlays(void);
virtual float GetHeadTurnRate( void );
virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
// CDefaultPlayerPickupVPhysics
void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ); void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason );
bool ShouldPlayIdleSound( void ); void IdleSound( void ); void DeathSound( const CTakeDamageInfo &info ); void AlertSound( void ); void PainSound( const CTakeDamageInfo &info ); virtual char *GetScannerSoundPrefix( void ) { return ""; } void ScannerEmitSound( const char *pszSoundName );
int MeleeAttack1Conditions ( float flDot, float flDist );
int SelectSchedule(void); void StartTask( const Task_t *pTask ); void OnScheduleChange( void ); void UpdateOnRemove( void ); virtual float GetMaxSpeed( void );
void PostRunStopMoving() {} // scanner can use "movement" activities but not be moving
virtual bool CanBecomeServerRagdoll( void ) { return false; }
void SpeakSentence( int sentenceType );
bool IsHeldByPhyscannon( void );
// Inputs
void InputSetFlightSpeed( inputdata_t &inputdata ); void InputSetDistanceOverride( inputdata_t &inputdata );
protected: virtual char *GetEngineSound( void ) { return NULL; } void PlayFlySound(void);
void SetBanking( float flInterval ); void UpdateHead( float flInterval ); inline CBaseEntity *EntityToWatch( void );
bool IsEnemyPlayerInSuit( void );
// Movement
virtual bool OverridePathMove( CBaseEntity *pMoveTarget, float flInterval ); virtual bool OverrideMove( float flInterval ); Vector IdealGoalForMovement( const Vector &goalPos, const Vector &startPos, float idealRange, float idealHeight ); virtual void AdjustScannerVelocity( void ) { return; } virtual void MoveToAttack(float flInterval); virtual void MoveToTarget( float flInterval, const Vector &vecMoveTarget ); virtual void MoveExecute_Alive(float flInterval); virtual float MinGroundDist(void) { return 64; } Vector VelocityToEvade(CBaseCombatCharacter *pEnemy); virtual float GetGoalDistance( void );
// Divebombing
virtual void AttackDivebomb( void ); void DiveBombSoundThink(); void AttackDivebombCollide(float flInterval); void MoveToDivebomb(float flInterval); void BlendPhyscannonLaunchSpeed();
private: bool GetGoalDirection( Vector *vOut );
void StartSmokeTrail( void );
// Take damage from being thrown by a physcannon
void TakeDamageFromPhyscannon( CBasePlayer *pPlayer );
// Take damage from physics impacts
void TakeDamageFromPhysicsImpact( int index, gamevcollisionevent_t *pEvent );
// Do we have a physics attacker?
CBasePlayer *HasPhysicsAttacker( float dt );
virtual void StopLoopingSounds(void);
public: // ------------------------
// Death Cleanup
// ------------------------
CTakeDamageInfo m_KilledInfo;
protected: ScannerFlyMode_t m_nFlyMode;
// Pose parameters
int m_nPoseTail; int m_nPoseDynamo; int m_nPoseFlare; int m_nPoseFaceVert; int m_nPoseFaceHoriz;
bool m_bHasSpoken;
// Movement
float m_flFlyNoiseBase; float m_flEngineStallTime; float m_fNextFlySoundTime; Vector m_vecDiveBombDirection; // The direction we dive bomb. Calculated at the moment of death.
float m_flDiveBombRollForce; // Used for roll while dive bombing.
float m_flGoalOverrideDistance;
// Deriver scanner variables
float m_flAttackNearDist; float m_flAttackFarDist; float m_flAttackRange;
private: CSoundPatch *m_pEngineSound;
// physics influence
CHandle<CBasePlayer> m_hPhysicsAttacker; float m_flLastPhysicsInfluenceTime;
// Attacks
SmokeTrail *m_pSmokeTrail;
protected: DEFINE_CUSTOM_AI;
// Custom interrupt conditions
enum { COND_SCANNER_FLY_CLEAR = BaseClass::NEXT_CONDITION, COND_SCANNER_FLY_BLOCKED, COND_SCANNER_GRABBED_BY_PHYSCANNON, COND_SCANNER_RELEASED_FROM_PHYSCANNON,
NEXT_CONDITION, };
// Custom schedules
enum { SCHED_SCANNER_PATROL = BaseClass::NEXT_SCHEDULE, SCHED_SCANNER_ATTACK, SCHED_SCANNER_ATTACK_HOVER, SCHED_SCANNER_ATTACK_DIVEBOMB, SCHED_SCANNER_CHASE_ENEMY, SCHED_SCANNER_CHASE_TARGET, SCHED_SCANNER_FOLLOW_HOVER, SCHED_SCANNER_HELD_BY_PHYSCANNON,
NEXT_SCHEDULE, };
// Custom tasks
enum { TASK_SCANNER_SET_FLY_PATROL = BaseClass::NEXT_TASK, TASK_SCANNER_SET_FLY_CHASE, TASK_SCANNER_SET_FLY_ATTACK, TASK_SCANNER_SET_FLY_DIVE,
NEXT_TASK, };
DECLARE_DATADESC(); };
#endif // NPC_BASESCANNER_H
|