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.
|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
// headless_hatman.h
// An NPC that spawns in the Halloween map and wreaks havok
// Michael Booth, October 2010
#ifndef HEADLESS_HATMAN_H
#define HEADLESS_HATMAN_H
#include "NextBot.h"
#include "NextBotBehavior.h"
#include "NextBotGroundLocomotion.h"
#include "headless_hatman_body.h"
#include "Path/NextBotPathFollow.h"
#include "halloween_base_boss.h"
extern ConVar tf_halloween_bot_health_base; extern ConVar tf_halloween_bot_health_per_player; extern ConVar tf_halloween_bot_min_player_count;
extern ConVar tf_halloween_bot_speed; extern ConVar tf_halloween_bot_attack_range; extern ConVar tf_halloween_bot_speed_recovery_rate; extern ConVar tf_halloween_bot_speed_penalty; extern ConVar tf_halloween_bot_chase_duration; extern ConVar tf_halloween_bot_terrify_radius; extern ConVar tf_halloween_bot_chase_range; extern ConVar tf_halloween_bot_quit_range;
class CTFPlayer; class CHeadlessHatman;
//----------------------------------------------------------------------------
class CHeadlessHatmanLocomotion : public NextBotGroundLocomotion { public: CHeadlessHatmanLocomotion( INextBot *bot ) : NextBotGroundLocomotion( bot ) { } virtual ~CHeadlessHatmanLocomotion() { }
virtual float GetRunSpeed( void ) const; // get maximum running speed
virtual float GetStepHeight( void ) const; // if delta Z is greater than this, we have to jump to get up
virtual float GetMaxJumpHeight( void ) const; // return maximum height of a jump
/**
* Should we collide with this entity? */ virtual bool ShouldCollideWith( const CBaseEntity *object ) const;
private: virtual float GetMaxYawRate( void ) const; // return max rate of yaw rotation
};
//----------------------------------------------------------------------------
class CHeadlessHatmanIntention : public IIntention { public: CHeadlessHatmanIntention( CHeadlessHatman *me ); virtual ~CHeadlessHatmanIntention();
virtual void Reset( void ); virtual void Update( void );
virtual QueryResultType IsPositionAllowed( const INextBot *me, const Vector &pos ) const; // is the a place we can be?
virtual INextBotEventResponder *FirstContainedResponder( void ) const { return m_behavior; } virtual INextBotEventResponder *NextContainedResponder( INextBotEventResponder *current ) const { return NULL; }
private: Behavior< CHeadlessHatman > *m_behavior; };
//----------------------------------------------------------------------------
class CHeadlessHatman : public CHalloweenBaseBoss { public: DECLARE_CLASS( CHeadlessHatman, CHalloweenBaseBoss ); DECLARE_SERVERCLASS();
CHeadlessHatman(); virtual ~CHeadlessHatman();
static void PrecacheHeadlessHatman(); virtual void Precache(); virtual void Spawn( void );
virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
// INextBot
virtual CHeadlessHatmanIntention *GetIntentionInterface( void ) const { return m_intention; } virtual CHeadlessHatmanLocomotion *GetLocomotionInterface( void ) const { return m_locomotor; } virtual CHeadlessHatmanBody *GetBodyInterface( void ) const { return m_body; }
virtual void Update( void );
const Vector &GetHomePosition( void ) const;
CBaseAnimating *GetAxe( void ) const;
virtual HalloweenBossType GetBossType() const { return HALLOWEEN_BOSS_HHH; }
private: const char *GetWeaponModel() const;
CHeadlessHatmanIntention *m_intention; CHeadlessHatmanLocomotion *m_locomotor; CHeadlessHatmanBody *m_body;
CBaseAnimating *m_axe;
CUtlVector< AttackerInfo > m_attackerVector; // list of everyone who injured me, and when
CountdownTimer m_painTimer;
Vector m_homePos; int m_damagePoseParameter; };
inline CBaseAnimating *CHeadlessHatman::GetAxe( void ) const { return m_axe; }
inline const Vector &CHeadlessHatman::GetHomePosition( void ) const { return m_homePos; }
//--------------------------------------------------------------------------------------------------------------
class CHeadlessHatmanPathCost : public IPathCost { public: CHeadlessHatmanPathCost( CHeadlessHatman *me ) { m_me = me; }
// return the cost (weighted distance between) of moving from "fromArea" to "area", or -1 if the move is not allowed
virtual float operator()( CNavArea *area, CNavArea *fromArea, const CNavLadder *ladder, const CFuncElevator *elevator, float length ) const { if ( fromArea == NULL ) { // first area in path, no cost
return 0.0f; } else { if ( !m_me->GetLocomotionInterface()->IsAreaTraversable( area ) ) { // our locomotor says we can't move here
return -1.0f; }
// compute distance traveled along path so far
float dist;
if ( ladder ) { dist = ladder->m_length; } else if ( length > 0.0 ) { // optimization to avoid recomputing length
dist = length; } else { dist = ( area->GetCenter() - fromArea->GetCenter() ).Length(); }
float cost = dist + fromArea->GetCostSoFar();
// check height change
float deltaZ = fromArea->ComputeAdjacentConnectionHeightChange( area ); if ( deltaZ >= m_me->GetLocomotionInterface()->GetStepHeight() ) { if ( deltaZ >= m_me->GetLocomotionInterface()->GetMaxJumpHeight() ) { // too high to reach
return -1.0f; }
// jumping is slower than flat ground
const float jumpPenalty = 5.0f; cost += jumpPenalty * dist; } else if ( deltaZ < -m_me->GetLocomotionInterface()->GetDeathDropHeight() ) { // too far to drop
return -1.0f; }
return cost; } }
CHeadlessHatman *m_me; };
#endif // HEADLESS_HATMAN_H
|