diff options
Diffstat (limited to 'game/server/hl2/npc_BaseZombie.h')
| -rw-r--r-- | game/server/hl2/npc_BaseZombie.h | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/game/server/hl2/npc_BaseZombie.h b/game/server/hl2/npc_BaseZombie.h new file mode 100644 index 0000000..d4800f3 --- /dev/null +++ b/game/server/hl2/npc_BaseZombie.h @@ -0,0 +1,291 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef NPC_BASEZOMBIE_H +#define NPC_BASEZOMBIE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "ai_basenpc.h" +#include "ai_blended_movement.h" +#include "soundenvelope.h" +#include "ai_behavior_actbusy.h" + +#define ZOM_ATTN_FOOTSTEP ATTN_IDLE + +#define ENVELOPE_CONTROLLER (CSoundEnvelopeController::GetController()) + +#define ZOMBIE_MELEE_REACH 55 + +extern int AE_ZOMBIE_ATTACK_RIGHT; +extern int AE_ZOMBIE_ATTACK_LEFT; +extern int AE_ZOMBIE_ATTACK_BOTH; +extern int AE_ZOMBIE_SWATITEM; +extern int AE_ZOMBIE_STARTSWAT; +extern int AE_ZOMBIE_STEP_LEFT; +extern int AE_ZOMBIE_STEP_RIGHT; +extern int AE_ZOMBIE_SCUFF_LEFT; +extern int AE_ZOMBIE_SCUFF_RIGHT; +extern int AE_ZOMBIE_ATTACK_SCREAM; +extern int AE_ZOMBIE_GET_UP; +extern int AE_ZOMBIE_POUND; + +#define ZOMBIE_BODYGROUP_HEADCRAB 1 // The crab on our head + +// Pass these to claw attack so we know where to draw the blood. +#define ZOMBIE_BLOOD_LEFT_HAND 0 +#define ZOMBIE_BLOOD_RIGHT_HAND 1 +#define ZOMBIE_BLOOD_BOTH_HANDS 2 +#define ZOMBIE_BLOOD_BITE 3 + + +enum HeadcrabRelease_t +{ + RELEASE_NO, + RELEASE_IMMEDIATE, // release the headcrab right now! + RELEASE_SCHEDULED, // release the headcrab through the AI schedule. + RELEASE_VAPORIZE, // just destroy the crab. + RELEASE_RAGDOLL, // release a dead crab + RELEASE_RAGDOLL_SLICED_OFF // toss the crab up a bit +}; + + +//========================================================= +// schedules +//========================================================= +enum +{ + SCHED_ZOMBIE_CHASE_ENEMY = LAST_SHARED_SCHEDULE, + SCHED_ZOMBIE_MOVE_SWATITEM, + SCHED_ZOMBIE_SWATITEM, + SCHED_ZOMBIE_ATTACKITEM, + SCHED_ZOMBIE_RELEASECRAB, + SCHED_ZOMBIE_MOVE_TO_AMBUSH, + SCHED_ZOMBIE_WAIT_AMBUSH, + SCHED_ZOMBIE_WANDER_MEDIUM, // medium range wandering behavior. + SCHED_ZOMBIE_WANDER_FAIL, + SCHED_ZOMBIE_WANDER_STANDOFF, + SCHED_ZOMBIE_MELEE_ATTACK1, + SCHED_ZOMBIE_POST_MELEE_WAIT, + + LAST_BASE_ZOMBIE_SCHEDULE, +}; + +//========================================================= +// tasks +//========================================================= +enum +{ + TASK_ZOMBIE_DELAY_SWAT = LAST_SHARED_TASK, + TASK_ZOMBIE_GET_PATH_TO_PHYSOBJ, + TASK_ZOMBIE_SWAT_ITEM, + TASK_ZOMBIE_DIE, + TASK_ZOMBIE_RELEASE_HEADCRAB, + TASK_ZOMBIE_WAIT_POST_MELEE, + + LAST_BASE_ZOMBIE_TASK, +}; + + +//========================================================= +// Zombie conditions +//========================================================= +enum Zombie_Conds +{ + COND_ZOMBIE_CAN_SWAT_ATTACK = LAST_SHARED_CONDITION, + COND_ZOMBIE_RELEASECRAB, + COND_ZOMBIE_LOCAL_MELEE_OBSTRUCTION, + + LAST_BASE_ZOMBIE_CONDITION, +}; + + + +typedef CAI_BlendingHost< CAI_BehaviorHost<CAI_BaseNPC> > CAI_BaseZombieBase; + +//========================================================= +//========================================================= +abstract_class CNPC_BaseZombie : public CAI_BaseZombieBase +{ + DECLARE_CLASS( CNPC_BaseZombie, CAI_BaseZombieBase ); + +public: + CNPC_BaseZombie( void ); + ~CNPC_BaseZombie( void ); + + void Spawn( void ); + void Precache( void ); + void StartTouch( CBaseEntity *pOther ); + bool CreateBehaviors(); + float MaxYawSpeed( void ); + bool OverrideMoveFacing( const AILocalMoveGoal_t &move, float flInterval ); + Class_T Classify( void ); + Disposition_t IRelationType( CBaseEntity *pTarget ); + void HandleAnimEvent( animevent_t *pEvent ); + + void OnStateChange( NPC_STATE OldState, NPC_STATE NewState ); + + void KillMe( void ) + { + m_iHealth = 5; + OnTakeDamage( CTakeDamageInfo( this, this, m_iHealth * 2, DMG_GENERIC ) ); + } + + int MeleeAttack1Conditions ( float flDot, float flDist ); + virtual float GetClawAttackRange() const { return ZOMBIE_MELEE_REACH; } + + // No range attacks + int RangeAttack1Conditions ( float flDot, float flDist ) { return( 0 ); } + + virtual float GetHitgroupDamageMultiplier( int iHitGroup, const CTakeDamageInfo &info ); + void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator ); + int OnTakeDamage_Alive( const CTakeDamageInfo &info ); + virtual float GetReactionDelay( CBaseEntity *pEnemy ) { return 0.0; } + + virtual int SelectSchedule ( void ); + virtual int SelectFailSchedule( int failedSchedule, int failedTask, AI_TaskFailureCode_t taskFailCode ); + virtual void BuildScheduleTestBits( void ); + + virtual int TranslateSchedule( int scheduleType ); + virtual Activity NPC_TranslateActivity( Activity baseAct ); + + void StartTask( const Task_t *pTask ); + void RunTask( const Task_t *pTask ); + + void GatherConditions( void ); + void PrescheduleThink( void ); + + virtual void Event_Killed( const CTakeDamageInfo &info ); + virtual bool BecomeRagdoll( const CTakeDamageInfo &info, const Vector &forceVector ); + void StopLoopingSounds(); + virtual void OnScheduleChange( void ); + + virtual void PoundSound(); + + // Custom damage/death + bool ShouldIgnite( const CTakeDamageInfo &info ); + bool ShouldIgniteZombieGib( void ); + virtual bool IsChopped( const CTakeDamageInfo &info ); + virtual bool IsSquashed( const CTakeDamageInfo &info ) { return false; } + virtual void DieChopped( const CTakeDamageInfo &info ); + virtual void Ignite( float flFlameLifetime, bool bNPCOnly = true, float flSize = 0.0f, bool bCalledByLevelDesigner = false ); + void CopyRenderColorTo( CBaseEntity *pOther ); + + virtual bool ShouldBecomeTorso( const CTakeDamageInfo &info, float flDamageThreshold ); + virtual HeadcrabRelease_t ShouldReleaseHeadcrab( const CTakeDamageInfo &info, float flDamageThreshold ); + + // Headcrab releasing/breaking apart + void RemoveHead( void ); + virtual void SetZombieModel( void ) { }; + virtual void BecomeTorso( const Vector &vecTorsoForce, const Vector &vecLegsForce ); + virtual bool CanBecomeLiveTorso() { return false; } + virtual bool HeadcrabFits( CBaseAnimating *pCrab ); + void ReleaseHeadcrab( const Vector &vecOrigin, const Vector &vecVelocity, bool fRemoveHead, bool fRagdollBody, bool fRagdollCrab = false ); + void SetHeadcrabSpawnLocation( int iCrabAttachment, CBaseAnimating *pCrab ); + + // Slumping/sleeping + bool IsSlumped( void ); + bool IsGettingUp( void ); + + // Swatting physics objects + int GetSwatActivity( void ); + bool FindNearestPhysicsObject( int iMaxMass ); + float DistToPhysicsEnt( void ); + virtual bool CanSwatPhysicsObjects( void ) { return true; } + + // Returns whether we must be very near our enemy to attack them. + virtual bool MustCloseToAttack(void) { return true; } + + virtual CBaseEntity *ClawAttack( float flDist, int iDamage, QAngle &qaViewPunch, Vector &vecVelocityPunch, int BloodOrigin ); + + // Sounds & sound envelope + virtual bool ShouldPlayFootstepMoan( void ); + virtual void PainSound( const CTakeDamageInfo &info ) = 0; + virtual void AlertSound( void ) = 0; + virtual void IdleSound( void ) = 0; + virtual void AttackSound( void ) = 0; + virtual void AttackHitSound( void ) = 0; + virtual void AttackMissSound( void ) = 0; + virtual void FootstepSound( bool fRightFoot ) = 0; + virtual void FootscuffSound( bool fRightFoot ) = 0; + + // make a sound Alyx can hear when in darkness mode + void MakeAISpookySound( float volume, float duration = 0.5 ); + + virtual bool CanPlayMoanSound(); + virtual void MoanSound( envelopePoint_t *pEnvelope, int iEnvelopeSize ); + bool ShouldPlayIdleSound( void ) { return false; } + + virtual const char *GetMoanSound( int nSound ) = 0; + virtual const char *GetHeadcrabClassname( void ) = 0; + virtual const char *GetLegsModel( void ) = 0; + virtual const char *GetTorsoModel( void ) = 0; + virtual const char *GetHeadcrabModel( void ) = 0; + + virtual Vector BodyTarget( const Vector &posSrc, bool bNoisy ); + virtual Vector HeadTarget( const Vector &posSrc ); + virtual float GetAutoAimRadius(); + virtual void TranslateNavGoal( CBaseEntity *pEnemy, Vector &chasePosition ); + + bool OnInsufficientStopDist( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult ); + + virtual bool AllowedToIgnite( void ) { return true; } + +public: + CAI_ActBusyBehavior m_ActBusyBehavior; + + + +protected: + + CSoundPatch *m_pMoanSound; + + bool m_fIsTorso; // is this is a half-zombie? + bool m_fIsHeadless; // is this zombie headless + + float m_flNextFlinch; + + bool m_bHeadShot; // Used to determine the survival of our crab beyond our death. + + // + // Zombies catch on fire if they take too much burn damage in a given time period. + // + float m_flBurnDamage; // Keeps track of how much burn damage we've incurred in the last few seconds. + float m_flBurnDamageResetTime; // Time at which we reset the burn damage. + + EHANDLE m_hPhysicsEnt; + + float m_flNextMoanSound; + float m_flNextSwat; + float m_flNextSwatScan; + float m_crabHealth; + float m_flMoanPitch; + + EHANDLE m_hObstructor; + + static int g_numZombies; // counts total number of existing zombies. + + int m_iMoanSound; // each zombie picks one of the 4 and keeps it. + + static int ACT_ZOM_SWATLEFTMID; + static int ACT_ZOM_SWATRIGHTMID; + static int ACT_ZOM_SWATLEFTLOW; + static int ACT_ZOM_SWATRIGHTLOW; + static int ACT_ZOM_RELEASECRAB; + static int ACT_ZOM_FALL; + + DECLARE_DATADESC(); + + DEFINE_CUSTOM_AI; + +private: + bool m_bIsSlumped; + +}; + +#endif // NPC_BASEZOMBIE_H |