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.

205 lines
5.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. // headless_hatman.h
  3. // An NPC that spawns in the Halloween map and wreaks havok
  4. // Michael Booth, October 2010
  5. #ifndef HEADLESS_HATMAN_H
  6. #define HEADLESS_HATMAN_H
  7. #include "NextBot.h"
  8. #include "NextBotBehavior.h"
  9. #include "NextBotGroundLocomotion.h"
  10. #include "headless_hatman_body.h"
  11. #include "Path/NextBotPathFollow.h"
  12. #include "halloween_base_boss.h"
  13. extern ConVar tf_halloween_bot_health_base;
  14. extern ConVar tf_halloween_bot_health_per_player;
  15. extern ConVar tf_halloween_bot_min_player_count;
  16. extern ConVar tf_halloween_bot_speed;
  17. extern ConVar tf_halloween_bot_attack_range;
  18. extern ConVar tf_halloween_bot_speed_recovery_rate;
  19. extern ConVar tf_halloween_bot_speed_penalty;
  20. extern ConVar tf_halloween_bot_chase_duration;
  21. extern ConVar tf_halloween_bot_terrify_radius;
  22. extern ConVar tf_halloween_bot_chase_range;
  23. extern ConVar tf_halloween_bot_quit_range;
  24. class CTFPlayer;
  25. class CHeadlessHatman;
  26. //----------------------------------------------------------------------------
  27. class CHeadlessHatmanLocomotion : public NextBotGroundLocomotion
  28. {
  29. public:
  30. CHeadlessHatmanLocomotion( INextBot *bot ) : NextBotGroundLocomotion( bot ) { }
  31. virtual ~CHeadlessHatmanLocomotion() { }
  32. virtual float GetRunSpeed( void ) const; // get maximum running speed
  33. virtual float GetStepHeight( void ) const; // if delta Z is greater than this, we have to jump to get up
  34. virtual float GetMaxJumpHeight( void ) const; // return maximum height of a jump
  35. /**
  36. * Should we collide with this entity?
  37. */
  38. virtual bool ShouldCollideWith( const CBaseEntity *object ) const;
  39. private:
  40. virtual float GetMaxYawRate( void ) const; // return max rate of yaw rotation
  41. };
  42. //----------------------------------------------------------------------------
  43. class CHeadlessHatmanIntention : public IIntention
  44. {
  45. public:
  46. CHeadlessHatmanIntention( CHeadlessHatman *me );
  47. virtual ~CHeadlessHatmanIntention();
  48. virtual void Reset( void );
  49. virtual void Update( void );
  50. virtual QueryResultType IsPositionAllowed( const INextBot *me, const Vector &pos ) const; // is the a place we can be?
  51. virtual INextBotEventResponder *FirstContainedResponder( void ) const { return m_behavior; }
  52. virtual INextBotEventResponder *NextContainedResponder( INextBotEventResponder *current ) const { return NULL; }
  53. private:
  54. Behavior< CHeadlessHatman > *m_behavior;
  55. };
  56. //----------------------------------------------------------------------------
  57. class CHeadlessHatman : public CHalloweenBaseBoss
  58. {
  59. public:
  60. DECLARE_CLASS( CHeadlessHatman, CHalloweenBaseBoss );
  61. DECLARE_SERVERCLASS();
  62. CHeadlessHatman();
  63. virtual ~CHeadlessHatman();
  64. static void PrecacheHeadlessHatman();
  65. virtual void Precache();
  66. virtual void Spawn( void );
  67. virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  68. // INextBot
  69. virtual CHeadlessHatmanIntention *GetIntentionInterface( void ) const { return m_intention; }
  70. virtual CHeadlessHatmanLocomotion *GetLocomotionInterface( void ) const { return m_locomotor; }
  71. virtual CHeadlessHatmanBody *GetBodyInterface( void ) const { return m_body; }
  72. virtual void Update( void );
  73. const Vector &GetHomePosition( void ) const;
  74. CBaseAnimating *GetAxe( void ) const;
  75. virtual HalloweenBossType GetBossType() const { return HALLOWEEN_BOSS_HHH; }
  76. private:
  77. const char *GetWeaponModel() const;
  78. CHeadlessHatmanIntention *m_intention;
  79. CHeadlessHatmanLocomotion *m_locomotor;
  80. CHeadlessHatmanBody *m_body;
  81. CBaseAnimating *m_axe;
  82. CUtlVector< AttackerInfo > m_attackerVector; // list of everyone who injured me, and when
  83. CountdownTimer m_painTimer;
  84. Vector m_homePos;
  85. int m_damagePoseParameter;
  86. };
  87. inline CBaseAnimating *CHeadlessHatman::GetAxe( void ) const
  88. {
  89. return m_axe;
  90. }
  91. inline const Vector &CHeadlessHatman::GetHomePosition( void ) const
  92. {
  93. return m_homePos;
  94. }
  95. //--------------------------------------------------------------------------------------------------------------
  96. class CHeadlessHatmanPathCost : public IPathCost
  97. {
  98. public:
  99. CHeadlessHatmanPathCost( CHeadlessHatman *me )
  100. {
  101. m_me = me;
  102. }
  103. // return the cost (weighted distance between) of moving from "fromArea" to "area", or -1 if the move is not allowed
  104. virtual float operator()( CNavArea *area, CNavArea *fromArea, const CNavLadder *ladder, const CFuncElevator *elevator, float length ) const
  105. {
  106. if ( fromArea == NULL )
  107. {
  108. // first area in path, no cost
  109. return 0.0f;
  110. }
  111. else
  112. {
  113. if ( !m_me->GetLocomotionInterface()->IsAreaTraversable( area ) )
  114. {
  115. // our locomotor says we can't move here
  116. return -1.0f;
  117. }
  118. // compute distance traveled along path so far
  119. float dist;
  120. if ( ladder )
  121. {
  122. dist = ladder->m_length;
  123. }
  124. else if ( length > 0.0 )
  125. {
  126. // optimization to avoid recomputing length
  127. dist = length;
  128. }
  129. else
  130. {
  131. dist = ( area->GetCenter() - fromArea->GetCenter() ).Length();
  132. }
  133. float cost = dist + fromArea->GetCostSoFar();
  134. // check height change
  135. float deltaZ = fromArea->ComputeAdjacentConnectionHeightChange( area );
  136. if ( deltaZ >= m_me->GetLocomotionInterface()->GetStepHeight() )
  137. {
  138. if ( deltaZ >= m_me->GetLocomotionInterface()->GetMaxJumpHeight() )
  139. {
  140. // too high to reach
  141. return -1.0f;
  142. }
  143. // jumping is slower than flat ground
  144. const float jumpPenalty = 5.0f;
  145. cost += jumpPenalty * dist;
  146. }
  147. else if ( deltaZ < -m_me->GetLocomotionInterface()->GetDeathDropHeight() )
  148. {
  149. // too far to drop
  150. return -1.0f;
  151. }
  152. return cost;
  153. }
  154. }
  155. CHeadlessHatman *m_me;
  156. };
  157. #endif // HEADLESS_HATMAN_H