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.
344 lines
11 KiB
344 lines
11 KiB
//========= 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
|
|
|