Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.
 
 
 
 
 
 

256 lines
7.4 KiB

//========= 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