Team Fortress 2 Source Code as on 22/4/2020
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.

196 lines
5.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. //
  4. //
  5. //=============================================================================
  6. #ifndef ZOMBIE_H
  7. #define ZOMBIE_H
  8. #include "NextBot.h"
  9. #include "NextBotBehavior.h"
  10. #include "NextBotGroundLocomotion.h"
  11. #include "../headless_hatman_body.h"
  12. #include "Path/NextBotPathFollow.h"
  13. class CZombie;
  14. //----------------------------------------------------------------------------
  15. class CZombieLocomotion : public NextBotGroundLocomotion
  16. {
  17. public:
  18. CZombieLocomotion( INextBot *bot ) : NextBotGroundLocomotion( bot ) { }
  19. virtual ~CZombieLocomotion() { }
  20. virtual float GetRunSpeed( void ) const; // get maximum running speed
  21. virtual float GetStepHeight( void ) const; // if delta Z is greater than this, we have to jump to get up
  22. virtual float GetMaxJumpHeight( void ) const; // return maximum height of a jump
  23. virtual bool ShouldCollideWith( const CBaseEntity *object ) const;
  24. private:
  25. virtual float GetMaxYawRate( void ) const; // return max rate of yaw rotation
  26. };
  27. //----------------------------------------------------------------------------
  28. class CZombieIntention : public IIntention
  29. {
  30. public:
  31. CZombieIntention( CZombie *me );
  32. virtual ~CZombieIntention();
  33. virtual void Reset( void );
  34. virtual void Update( void );
  35. virtual QueryResultType IsPositionAllowed( const INextBot *me, const Vector &pos ) const; // is the a place we can be?
  36. virtual INextBotEventResponder *FirstContainedResponder( void ) const { return m_behavior; }
  37. virtual INextBotEventResponder *NextContainedResponder( INextBotEventResponder *current ) const { return NULL; }
  38. private:
  39. Behavior< CZombie > *m_behavior;
  40. };
  41. //----------------------------------------------------------------------------
  42. DECLARE_AUTO_LIST( IZombieAutoList );
  43. class CZombie : public NextBotCombatCharacter, public IZombieAutoList
  44. {
  45. public:
  46. DECLARE_CLASS( CZombie, NextBotCombatCharacter );
  47. DECLARE_SERVERCLASS();
  48. CZombie();
  49. virtual ~CZombie();
  50. static void PrecacheZombie();
  51. virtual void Precache();
  52. virtual void Spawn( void );
  53. virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  54. virtual void Event_Killed( const CTakeDamageInfo &info );
  55. virtual void UpdateOnRemove();
  56. // INextBot
  57. virtual CZombieIntention *GetIntentionInterface( void ) const { return m_intention; }
  58. virtual CZombieLocomotion *GetLocomotionInterface( void ) const { return m_locomotor; }
  59. virtual CHeadlessHatmanBody *GetBodyInterface( void ) const { return m_body; }
  60. CBaseAnimating *m_zombieParts;
  61. void StartLifeTimer( float flLifeTime ) { m_lifeTimer.Start( flLifeTime ); }
  62. bool ShouldSuicide() const;
  63. void ForceSuicide() { m_bForceSuicide = true; }
  64. enum SkeletonType_t
  65. {
  66. SKELETON_NORMAL = 0,
  67. SKELETON_KING,
  68. SKELETON_MINI
  69. };
  70. SkeletonType_t GetSkeletonType() const { return m_nType; }
  71. void SetSkeletonType( SkeletonType_t nType );
  72. void AddHat( const char *pszModel );
  73. static CZombie* SpawnAtPos( const Vector& vSpawnPos, float flLifeTime = 0.f, int nTeam = TF_TEAM_HALLOWEEN, CBaseEntity *pOwner = NULL, SkeletonType_t nSkeletonType = SKELETON_NORMAL );
  74. float GetAttackRange() const { return m_flAttackRange; }
  75. float GetAttackDamage() const { return m_flAttackDamage; }
  76. private:
  77. CZombieIntention *m_intention;
  78. CZombieLocomotion *m_locomotor;
  79. CHeadlessHatmanBody *m_body;
  80. SkeletonType_t m_nType;
  81. CNetworkVar( float, m_flHeadScale );
  82. CHandle< CBaseAnimating > m_hHat;
  83. float m_flAttackRange;
  84. float m_flAttackDamage;
  85. bool m_bSpy;
  86. bool m_bForceSuicide;
  87. CountdownTimer m_lifeTimer;
  88. };
  89. //--------------------------------------------------------------------------------------------------------------
  90. class CZombiePathCost : public IPathCost
  91. {
  92. public:
  93. CZombiePathCost( CZombie *me )
  94. {
  95. m_me = me;
  96. }
  97. // return the cost (weighted distance between) of moving from "fromArea" to "area", or -1 if the move is not allowed
  98. virtual float operator()( CNavArea *area, CNavArea *fromArea, const CNavLadder *ladder, const CFuncElevator *elevator, float length ) const
  99. {
  100. if ( fromArea == NULL )
  101. {
  102. // first area in path, no cost
  103. return 0.0f;
  104. }
  105. else
  106. {
  107. if ( !m_me->GetLocomotionInterface()->IsAreaTraversable( area ) )
  108. {
  109. // our locomotor says we can't move here
  110. return -1.0f;
  111. }
  112. // compute distance traveled along path so far
  113. float dist;
  114. if ( ladder )
  115. {
  116. dist = ladder->m_length;
  117. }
  118. else if ( length > 0.0 )
  119. {
  120. // optimization to avoid recomputing length
  121. dist = length;
  122. }
  123. else
  124. {
  125. dist = ( area->GetCenter() - fromArea->GetCenter() ).Length();
  126. }
  127. // check height change
  128. float deltaZ = fromArea->ComputeAdjacentConnectionHeightChange( area );
  129. if ( deltaZ >= m_me->GetLocomotionInterface()->GetStepHeight() )
  130. {
  131. if ( deltaZ >= m_me->GetLocomotionInterface()->GetMaxJumpHeight() )
  132. {
  133. // too high to reach
  134. return -1.0f;
  135. }
  136. // jumping is slower than flat ground
  137. const float jumpPenalty = 5.0f;
  138. dist += jumpPenalty * dist;
  139. }
  140. else if ( deltaZ < -m_me->GetLocomotionInterface()->GetDeathDropHeight() )
  141. {
  142. // too far to drop
  143. return -1.0f;
  144. }
  145. // this term causes the same bot to choose different routes over time,
  146. // but keep the same route for a period in case of repaths
  147. int timeMod = (int)( gpGlobals->curtime / 10.0f ) + 1;
  148. float preference = 1.0f + 50.0f * ( 1.0f + FastCos( (float)( m_me->GetEntity()->entindex() * area->GetID() * timeMod ) ) );
  149. float cost = dist * preference;
  150. return cost + fromArea->GetCostSoFar();;
  151. }
  152. }
  153. CZombie *m_me;
  154. };
  155. #endif // ZOMBIE_H