source-engine/game/server/hl2/npc_vortigaunt_episodic.h

345 lines
11 KiB
C
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: This is the base version of the vortigaunt
//
//=============================================================================//
#ifndef NPC_VORTIGAUNT_H
#define NPC_VORTIGAUNT_H
#ifdef _WIN32
#pragma once
#endif
#include "ai_basenpc.h"
#include "ai_behavior.h"
#include "ai_behavior_lead.h"
#include "ai_behavior_standoff.h"
#include "ai_behavior_assault.h"
#include "npc_playercompanion.h"
#define VORTIGAUNT_MAX_BEAMS 8
#define VORTIGAUNT_BEAM_ALL -1
#define VORTIGAUNT_BEAM_ZAP 0
#define VORTIGAUNT_BEAM_HEAL 1
#define VORTIGAUNT_BEAM_DISPEL 2
class CBeam;
class CSprite;
class CVortigauntChargeToken;
class CVortigauntEffectDispel;
extern ConVar sk_vortigaunt_zap_range;
enum VortigauntHealState_t
{
HEAL_STATE_NONE, // Not trying to heal
HEAL_STATE_WARMUP, // In the "warm-up" phase of healing
HEAL_STATE_HEALING, // In the process of healing
HEAL_STATE_COOLDOWN, // in the "cooldown" phase of healing
};
//=========================================================
// >> CNPC_Vortigaunt
//=========================================================
class CNPC_Vortigaunt : public CNPC_PlayerCompanion
{
DECLARE_CLASS( CNPC_Vortigaunt, CNPC_PlayerCompanion );
public:
CNPC_Vortigaunt( void );
virtual void Spawn( void );
virtual void Precache( void );
virtual float MaxYawSpeed( void );
virtual Vector FacingPosition( void );
virtual Vector BodyTarget( const Vector &posSrc, bool bNoisy = true );
virtual void PrescheduleThink( void );
virtual void BuildScheduleTestBits( void );
virtual void OnScheduleChange( void );
virtual int RangeAttack1Conditions( float flDot, float flDist ); // Primary zap
virtual int RangeAttack2Conditions( float flDot, float flDist ); // Concussive zap (larger)
virtual bool InnateWeaponLOSCondition( const Vector &ownerPos, const Vector &targetPos, bool bSetConditions );
virtual int MeleeAttack1Conditions( float flDot, float flDist ); // Dispel
virtual float InnateRange1MinRange( void ) { return 0.0f; }
virtual float InnateRange1MaxRange( void ) { return sk_vortigaunt_zap_range.GetFloat()*12; }
virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
virtual bool FInViewCone( CBaseEntity *pEntity );
virtual bool ShouldMoveAndShoot( void );
// vorts have a very long head/neck swing, so debounce heavily
virtual float GetHeadDebounce( void ) { return 0.7; } // how much of previous head turn to use
virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
virtual void AlertSound( void );
virtual Class_T Classify ( void ) { return IsGameEndAlly() ? CLASS_PLAYER_ALLY_VITAL : CLASS_VORTIGAUNT; }
virtual void HandleAnimEvent( animevent_t *pEvent );
virtual Activity NPC_TranslateActivity( Activity eNewActivity );
virtual void UpdateOnRemove( void );
virtual void Event_Killed( const CTakeDamageInfo &info );
virtual void GatherConditions( void );
virtual void RunTask( const Task_t *pTask );
virtual void StartTask( const Task_t *pTask );
virtual void ClearSchedule( const char *szReason );
virtual void DeclineFollowing( void );
virtual bool CanBeUsedAsAFriend( void );
virtual bool IsPlayerAlly( void ) { return true; }
// Override these to set behavior
virtual int TranslateSchedule( int scheduleType );
virtual int SelectSchedule( void );
virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode );
virtual bool IsValidEnemy( CBaseEntity *pEnemy );
bool IsLeading( void ) { return ( GetRunningBehavior() == &m_LeadBehavior && m_LeadBehavior.HasGoal() ); }
void DeathSound( const CTakeDamageInfo &info );
void PainSound( const CTakeDamageInfo &info );
virtual void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
virtual void SpeakSentence( int sentType );
virtual int IRelationPriority( CBaseEntity *pTarget );
virtual Disposition_t IRelationType( CBaseEntity *pTarget );
virtual bool IsReadinessCapable( void ) { return true; }
virtual float GetReadinessDecay() { return 30.0f; }
virtual bool ShouldRegenerateHealth( void ) { return m_bRegenerateHealth; }
virtual bool CanRunAScriptedNPCInteraction( bool bForced = false );
virtual void AimGun( void );
virtual void OnUpdateShotRegulator( void );
void InputEnableArmorRecharge( inputdata_t &data );
void InputDisableArmorRecharge( inputdata_t &data );
void InputExtractBugbait( inputdata_t &data );
void InputChargeTarget( inputdata_t &data );
void InputDispel( inputdata_t &data );
void InputBeginCarryNPC( inputdata_t &indputdata );
void InputEndCarryNPC( inputdata_t &indputdata );
// Health regeneration
void InputEnableHealthRegeneration( inputdata_t &data );
void InputDisableHealthRegeneration( inputdata_t &data );
// color
void InputTurnBlue( inputdata_t &data );
void InputTurnBlack( inputdata_t &data );
virtual void SetScriptedScheduleIgnoreConditions( Interruptability_t interrupt );
virtual void OnRestore( void );
virtual bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval );
virtual void OnStartScene( void );
virtual bool IsInterruptable( void );
virtual bool CanFlinch( void );
// used so a grub can notify me that I stepped on it. Says a line.
void OnSquishedGrub( const CBaseEntity *pGrub );
private:
int NumAntlionsInRadius( float flRadius );
void DispelAntlions( const Vector &vecOrigin, float flRadius, bool bDispel = true );
bool HealGestureHasLOS( void );
bool PlayerBelowHealthPercentage( CBasePlayer *pPlayer, float flPerc );
void StartHealing( void );
void StopHealing( bool bInterrupt = false );
void MaintainHealSchedule( void );
bool ShouldHealTarget( CBaseEntity *pTarget );
int SelectHealSchedule( void );
void CreateBeamBlast( const Vector &vecOrigin );
private:
//=========================================================
// Vortigaunt schedules
//=========================================================
enum
{
SCHED_VORTIGAUNT_STAND = BaseClass::NEXT_SCHEDULE,
SCHED_VORTIGAUNT_RANGE_ATTACK,
SCHED_VORTIGAUNT_HEAL,
SCHED_VORTIGAUNT_EXTRACT_BUGBAIT,
SCHED_VORTIGAUNT_FACE_PLAYER,
SCHED_VORTIGAUNT_RUN_TO_PLAYER,
SCHED_VORTIGAUNT_DISPEL_ANTLIONS,
SCHED_VORT_FLEE_FROM_BEST_SOUND,
SCHED_VORT_ALERT_FACE_BESTSOUND,
};
//=========================================================
// Vortigaunt Tasks
//=========================================================
enum
{
TASK_VORTIGAUNT_HEAL_WARMUP = BaseClass::NEXT_TASK,
TASK_VORTIGAUNT_HEAL,
TASK_VORTIGAUNT_EXTRACT_WARMUP,
TASK_VORTIGAUNT_EXTRACT,
TASK_VORTIGAUNT_EXTRACT_COOLDOWN,
TASK_VORTIGAUNT_FIRE_EXTRACT_OUTPUT,
TASK_VORTIGAUNT_WAIT_FOR_PLAYER,
TASK_VORTIGAUNT_GET_HEAL_TARGET,
TASK_VORTIGAUNT_DISPEL_ANTLIONS
};
//=========================================================
// Vortigaunt Conditions
//=========================================================
enum
{
COND_VORTIGAUNT_CAN_HEAL = BaseClass::NEXT_CONDITION,
COND_VORTIGAUNT_HEAL_TARGET_TOO_FAR, // Outside or heal range
COND_VORTIGAUNT_HEAL_TARGET_BLOCKED, // Blocked by an obstruction
COND_VORTIGAUNT_HEAL_TARGET_BEHIND_US, // Not within our "forward" range
COND_VORTIGAUNT_HEAL_VALID, // All conditions satisfied
COND_VORTIGAUNT_DISPEL_ANTLIONS, // Repulse all antlions around us
};
// ------------
// Beams
// ------------
inline bool InAttackSequence( void );
void ClearBeams( void );
void ArmBeam( int beamType, int nHand );
void ZapBeam( int nHand );
int m_nLightningSprite;
// ---------------
// Glow
// ----------------
void ClearHandGlow( void );
float m_fGlowAge;
float m_fGlowChangeTime;
bool m_bGlowTurningOn;
int m_nCurGlowIndex;
CHandle<CVortigauntEffectDispel> m_hHandEffect[2];
void StartHandGlow( int beamType, int nHand );
void EndHandGlow( int beamType = VORTIGAUNT_BEAM_ALL );
void MaintainGlows( void );
// ----------------
// Healing
// ----------------
bool m_bRegenerateHealth;
float m_flNextHealTime; // Next time allowed to heal player
EHANDLE m_hHealTarget; // The person that I'm going to heal.
bool m_bPlayerRequestedHeal; // This adds some priority to our heal (allows it to happen in combat, etc)
float m_flNextHealTokenTime;
VortigauntHealState_t m_eHealState;
CBaseEntity *FindHealTarget( void );
bool HealBehaviorAvailable( void );
void SetHealTarget( CBaseEntity *pTarget, bool bPlayerRequested );
void GatherHealConditions( void );
int m_nNumTokensToSpawn;
float m_flHealHinderedTime;
float m_flPainTime;
float m_nextLineFireTime;
bool m_bArmorRechargeEnabled;
bool m_bForceArmorRecharge;
float m_flDispelTestTime;
bool m_bExtractingBugbait;
bool IsCarryingNPC( void ) const { return m_bCarryingNPC; }
bool m_bCarryingNPC;
COutputEvent m_OnFinishedExtractingBugbait;
COutputEvent m_OnFinishedChargingTarget;
COutputEvent m_OnPlayerUse;
//Adrian: Let's do it the right way!
int m_iLeftHandAttachment;
int m_iRightHandAttachment;
bool m_bStopLoopingSounds;
float m_flAimDelay; // Amount of time to suppress aiming
// used for fading from green vort to blue vort
CNetworkVar( bool, m_bIsBlue );
CNetworkVar( float, m_flBlueEndFadeTime );
// used for fading to black
CNetworkVar( bool, m_bIsBlack );
public:
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
DEFINE_CUSTOM_AI;
};
//=============================================================================
//
// Charge Token
//
//=============================================================================
class CVortigauntChargeToken : public CBaseEntity
{
DECLARE_CLASS( CVortigauntChargeToken, CBaseEntity );
public:
static CVortigauntChargeToken *CreateChargeToken( const Vector &vecOrigin, CBaseEntity *pOwner, CBaseEntity *pTarget );
CVortigauntChargeToken( void );
virtual void Spawn( void );
virtual void Precache( void );
virtual unsigned int PhysicsSolidMaskForEntity( void ) const;
void FadeAndDie( void );
void SeekThink( void );
void SeekTouch( CBaseEntity *pOther );
void SetTargetEntity( CBaseEntity *pTarget ) { m_hTarget = pTarget; }
private:
Vector GetSteerVector( const Vector &vecForward );
float m_flLifetime;
EHANDLE m_hTarget;
CNetworkVar( bool, m_bFadeOut );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
};
//=============================================================================
//
// Dispel Effect
//
//=============================================================================
class CVortigauntEffectDispel : public CBaseEntity
{
DECLARE_CLASS( CVortigauntEffectDispel, CBaseEntity );
public:
static CVortigauntEffectDispel *CreateEffectDispel( const Vector &vecOrigin, CBaseEntity *pOwner, CBaseEntity *pTarget );
CVortigauntEffectDispel( void );
virtual void Spawn( void );
void FadeAndDie( void );
private:
CNetworkVar( bool, m_bFadeOut );
DECLARE_SERVERCLASS();
DECLARE_DATADESC();
};
#endif // NPC_VORTIGAUNT_H