This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

256 lines
7.8 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef NPC_BASESCANNER_H
#define NPC_BASESCANNER_H
#ifdef _WIN32
#pragma once
#endif
#include "ai_basenpc_physicsflyer.h"
#include "cbase.h"
#include "hl2_player.h"
#include "player_pickup.h"
#include "smoke_trail.h"
#include "weapon_physcannon.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