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.

610 lines
26 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Base combat character with no AI
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef BASECOMBATCHARACTER_H
  8. #define BASECOMBATCHARACTER_H
  9. #include <limits.h>
  10. #include "weapon_proficiency.h"
  11. #ifdef _WIN32
  12. #pragma once
  13. #endif
  14. #ifdef INVASION_DLL
  15. #include "tf_shareddefs.h"
  16. #define POWERUP_THINK_CONTEXT "PowerupThink"
  17. #endif
  18. #include "cbase.h"
  19. #include "baseentity.h"
  20. #include "baseflex.h"
  21. #include "damagemodifier.h"
  22. #include "utllinkedlist.h"
  23. #include "ai_hull.h"
  24. #include "ai_utils.h"
  25. #include "physics_impact_damage.h"
  26. #ifdef TF_DLL
  27. #include "tf_shareddefs.h"
  28. #endif // TF_DLL
  29. class CNavArea;
  30. class CScriptedTarget;
  31. typedef CHandle<CBaseCombatWeapon> CBaseCombatWeaponHandle;
  32. // -------------------------------------
  33. // Capability Bits
  34. // -------------------------------------
  35. enum Capability_t
  36. {
  37. bits_CAP_MOVE_GROUND = 0x00000001, // walk/run
  38. bits_CAP_MOVE_JUMP = 0x00000002, // jump/leap
  39. bits_CAP_MOVE_FLY = 0x00000004, // can fly, move all around
  40. bits_CAP_MOVE_CLIMB = 0x00000008, // climb ladders
  41. bits_CAP_MOVE_SWIM = 0x00000010, // navigate in water // UNDONE - not yet implemented
  42. bits_CAP_MOVE_CRAWL = 0x00000020, // crawl // UNDONE - not yet implemented
  43. bits_CAP_MOVE_SHOOT = 0x00000040, // tries to shoot weapon while moving
  44. bits_CAP_SKIP_NAV_GROUND_CHECK = 0x00000080, // optimization - skips ground tests while computing navigation
  45. bits_CAP_USE = 0x00000100, // open doors/push buttons/pull levers
  46. //bits_CAP_HEAR = 0x00000200, // can hear forced sounds
  47. bits_CAP_AUTO_DOORS = 0x00000400, // can trigger auto doors
  48. bits_CAP_OPEN_DOORS = 0x00000800, // can open manual doors
  49. bits_CAP_TURN_HEAD = 0x00001000, // can turn head, always bone controller 0
  50. bits_CAP_WEAPON_RANGE_ATTACK1 = 0x00002000, // can do a weapon range attack 1
  51. bits_CAP_WEAPON_RANGE_ATTACK2 = 0x00004000, // can do a weapon range attack 2
  52. bits_CAP_WEAPON_MELEE_ATTACK1 = 0x00008000, // can do a weapon melee attack 1
  53. bits_CAP_WEAPON_MELEE_ATTACK2 = 0x00010000, // can do a weapon melee attack 2
  54. bits_CAP_INNATE_RANGE_ATTACK1 = 0x00020000, // can do a innate range attack 1
  55. bits_CAP_INNATE_RANGE_ATTACK2 = 0x00040000, // can do a innate range attack 1
  56. bits_CAP_INNATE_MELEE_ATTACK1 = 0x00080000, // can do a innate melee attack 1
  57. bits_CAP_INNATE_MELEE_ATTACK2 = 0x00100000, // can do a innate melee attack 1
  58. bits_CAP_USE_WEAPONS = 0x00200000, // can use weapons (non-innate attacks)
  59. //bits_CAP_STRAFE = 0x00400000, // strafe ( walk/run sideways)
  60. bits_CAP_ANIMATEDFACE = 0x00800000, // has animated eyes/face
  61. bits_CAP_USE_SHOT_REGULATOR = 0x01000000, // Uses the shot regulator for range attack1
  62. bits_CAP_FRIENDLY_DMG_IMMUNE = 0x02000000, // don't take damage from npc's that are D_LI
  63. bits_CAP_SQUAD = 0x04000000, // can form squads
  64. bits_CAP_DUCK = 0x08000000, // cover and reload ducking
  65. bits_CAP_NO_HIT_PLAYER = 0x10000000, // don't hit players
  66. bits_CAP_AIM_GUN = 0x20000000, // Use arms to aim gun, not just body
  67. bits_CAP_NO_HIT_SQUADMATES = 0x40000000, // none
  68. bits_CAP_SIMPLE_RADIUS_DAMAGE = 0x80000000, // Do not use robust radius damage model on this character.
  69. };
  70. #define bits_CAP_DOORS_GROUP (bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS)
  71. #define bits_CAP_RANGE_ATTACK_GROUP (bits_CAP_WEAPON_RANGE_ATTACK1 | bits_CAP_WEAPON_RANGE_ATTACK2)
  72. #define bits_CAP_MELEE_ATTACK_GROUP (bits_CAP_WEAPON_MELEE_ATTACK1 | bits_CAP_WEAPON_MELEE_ATTACK2)
  73. class CBaseCombatWeapon;
  74. #define BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE 0.9f
  75. enum Disposition_t
  76. {
  77. D_ER, // Undefined - error
  78. D_HT, // Hate
  79. D_FR, // Fear
  80. D_LI, // Like
  81. D_NU // Neutral
  82. };
  83. const int DEF_RELATIONSHIP_PRIORITY = INT_MIN;
  84. struct Relationship_t
  85. {
  86. EHANDLE entity; // Relationship to a particular entity
  87. Class_T classType; // Relationship to a class CLASS_NONE = not class based (Def. in baseentity.h)
  88. Disposition_t disposition; // D_HT (Hate), D_FR (Fear), D_LI (Like), D_NT (Neutral)
  89. int priority; // Relative importance of this relationship (higher numbers mean more important)
  90. DECLARE_SIMPLE_DATADESC();
  91. };
  92. //-----------------------------------------------------------------------------
  93. // Purpose: This should contain all of the combat entry points / functionality
  94. // that are common between NPCs and players
  95. //-----------------------------------------------------------------------------
  96. class CBaseCombatCharacter : public CBaseFlex
  97. {
  98. DECLARE_CLASS( CBaseCombatCharacter, CBaseFlex );
  99. public:
  100. CBaseCombatCharacter(void);
  101. ~CBaseCombatCharacter(void);
  102. DECLARE_SERVERCLASS();
  103. DECLARE_DATADESC();
  104. DECLARE_PREDICTABLE();
  105. public:
  106. virtual void Spawn( void );
  107. virtual void Precache();
  108. virtual int Restore( IRestore &restore );
  109. virtual const impactdamagetable_t &GetPhysicsImpactDamageTable( void );
  110. int TakeHealth( float flHealth, int bitsDamageType );
  111. void CauseDeath( const CTakeDamageInfo &info );
  112. virtual bool FVisible ( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); // true iff the parameter can be seen by me.
  113. virtual bool FVisible( const Vector &vecTarget, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ) { return BaseClass::FVisible( vecTarget, traceMask, ppBlocker ); }
  114. static void ResetVisibilityCache( CBaseCombatCharacter *pBCC = NULL );
  115. #ifdef PORTAL
  116. virtual bool FVisibleThroughPortal( const CProp_Portal *pPortal, CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );
  117. #endif
  118. virtual bool FInViewCone( CBaseEntity *pEntity );
  119. virtual bool FInViewCone( const Vector &vecSpot );
  120. #ifdef PORTAL
  121. virtual CProp_Portal* FInViewConeThroughPortal( CBaseEntity *pEntity );
  122. virtual CProp_Portal* FInViewConeThroughPortal( const Vector &vecSpot );
  123. #endif
  124. virtual bool FInAimCone( CBaseEntity *pEntity );
  125. virtual bool FInAimCone( const Vector &vecSpot );
  126. virtual bool ShouldShootMissTarget( CBaseCombatCharacter *pAttacker );
  127. virtual CBaseEntity *FindMissTarget( void );
  128. // Do not call HandleInteraction directly, use DispatchInteraction
  129. bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return ( interactionType > 0 ) ? HandleInteraction( interactionType, data, sourceEnt ) : false; }
  130. virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt );
  131. virtual QAngle BodyAngles();
  132. virtual Vector BodyDirection2D( void );
  133. virtual Vector BodyDirection3D( void );
  134. virtual Vector HeadDirection2D( void ) { return BodyDirection2D( ); }; // No head motion so just return body dir
  135. virtual Vector HeadDirection3D( void ) { return BodyDirection2D( ); }; // No head motion so just return body dir
  136. virtual Vector EyeDirection2D( void ) { return HeadDirection2D( ); }; // No eye motion so just return head dir
  137. virtual Vector EyeDirection3D( void ) { return HeadDirection3D( ); }; // No eye motion so just return head dir
  138. virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
  139. // -----------------------
  140. // Fog
  141. // -----------------------
  142. virtual bool IsHiddenByFog( const Vector &target ) const; ///< return true if given target cant be seen because of fog
  143. virtual bool IsHiddenByFog( CBaseEntity *target ) const; ///< return true if given target cant be seen because of fog
  144. virtual bool IsHiddenByFog( float range ) const; ///< return true if given distance is too far to see through the fog
  145. virtual float GetFogObscuredRatio( const Vector &target ) const;///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
  146. virtual float GetFogObscuredRatio( CBaseEntity *target ) const; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
  147. virtual float GetFogObscuredRatio( float range ) const; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
  148. // -----------------------
  149. // Vision
  150. // -----------------------
  151. enum FieldOfViewCheckType { USE_FOV, DISREGARD_FOV };
  152. // Visible starts with line of sight, and adds all the extra game checks like fog, smoke, camo...
  153. bool IsAbleToSee( const CBaseEntity *entity, FieldOfViewCheckType checkFOV );
  154. bool IsAbleToSee( CBaseCombatCharacter *pBCC, FieldOfViewCheckType checkFOV );
  155. virtual bool IsLookingTowards( const CBaseEntity *target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE ) const; // return true if our view direction is pointing at the given target, within the cosine of the angular tolerance. LINE OF SIGHT IS NOT CHECKED.
  156. virtual bool IsLookingTowards( const Vector &target, float cosTolerance = BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE ) const; // return true if our view direction is pointing at the given target, within the cosine of the angular tolerance. LINE OF SIGHT IS NOT CHECKED.
  157. virtual bool IsInFieldOfView( CBaseEntity *entity ) const; // Calls IsLookingTowards with the current field of view.
  158. virtual bool IsInFieldOfView( const Vector &pos ) const;
  159. enum LineOfSightCheckType
  160. {
  161. IGNORE_NOTHING,
  162. IGNORE_ACTORS
  163. };
  164. virtual bool IsLineOfSightClear( CBaseEntity *entity, LineOfSightCheckType checkType = IGNORE_NOTHING ) const;// strictly LOS check with no other considerations
  165. virtual bool IsLineOfSightClear( const Vector &pos, LineOfSightCheckType checkType = IGNORE_NOTHING, CBaseEntity *entityToIgnore = NULL ) const;
  166. // -----------------------
  167. // Ammo
  168. // -----------------------
  169. virtual int GiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound = false );
  170. int GiveAmmo( int iCount, const char *szName, bool bSuppressSound = false );
  171. virtual void RemoveAmmo( int iCount, int iAmmoIndex );
  172. virtual void RemoveAmmo( int iCount, const char *szName );
  173. void RemoveAllAmmo( );
  174. virtual int GetAmmoCount( int iAmmoIndex ) const;
  175. int GetAmmoCount( char *szName ) const;
  176. virtual Activity NPC_TranslateActivity( Activity baseAct );
  177. // -----------------------
  178. // Weapons
  179. // -----------------------
  180. CBaseCombatWeapon* Weapon_Create( const char *pWeaponName );
  181. virtual Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL );
  182. void Weapon_SetActivity( Activity newActivity, float duration );
  183. virtual void Weapon_FrameUpdate( void );
  184. virtual void Weapon_HandleAnimEvent( animevent_t *pEvent );
  185. CBaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class
  186. virtual bool Weapon_CanUse( CBaseCombatWeapon *pWeapon ); // True is allowed to use this class of weapon
  187. virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon ); // Adds weapon to player
  188. virtual bool Weapon_EquipAmmoOnly( CBaseCombatWeapon *pWeapon ); // Adds weapon ammo to player, leaves weapon
  189. bool Weapon_Detach( CBaseCombatWeapon *pWeapon ); // Clear any pointers to the weapon.
  190. virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget = NULL, const Vector *pVelocity = NULL );
  191. virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed)
  192. virtual Vector Weapon_ShootPosition( ); // gun position at current position/orientation
  193. bool Weapon_IsOnGround( CBaseCombatWeapon *pWeapon );
  194. CBaseEntity* Weapon_FindUsable( const Vector &range ); // search for a usable weapon in this range
  195. virtual bool Weapon_CanSwitchTo(CBaseCombatWeapon *pWeapon);
  196. virtual bool Weapon_SlotOccupied( CBaseCombatWeapon *pWeapon );
  197. virtual CBaseCombatWeapon *Weapon_GetSlot( int slot ) const;
  198. CBaseCombatWeapon *Weapon_GetWpnForAmmo( int iAmmoIndex );
  199. // For weapon strip
  200. void Weapon_DropAll( bool bDisallowWeaponPickup = false );
  201. virtual bool AddPlayerItem( CBaseCombatWeapon *pItem ) { return false; }
  202. virtual bool RemovePlayerItem( CBaseCombatWeapon *pItem ) { return false; }
  203. virtual bool CanBecomeServerRagdoll( void ) { return true; }
  204. // -----------------------
  205. // Damage
  206. // -----------------------
  207. // Don't override this for characters, override the per-life-state versions below
  208. virtual int OnTakeDamage( const CTakeDamageInfo &info );
  209. // Override these to control how your character takes damage in different states
  210. virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  211. virtual int OnTakeDamage_Dying( const CTakeDamageInfo &info );
  212. virtual int OnTakeDamage_Dead( const CTakeDamageInfo &info );
  213. virtual float GetAliveDuration( void ) const; // return time we have been alive (only valid when alive)
  214. virtual void OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker ) {}
  215. virtual void NotifyFriendsOfDamage( CBaseEntity *pAttackerEntity ) {}
  216. virtual bool HasEverBeenInjured( int team = TEAM_ANY ) const; // return true if we have ever been injured by a member of the given team
  217. virtual float GetTimeSinceLastInjury( int team = TEAM_ANY ) const; // return time since we were hurt by a member of the given team
  218. virtual void OnPlayerKilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) {}
  219. // utility function to calc damage force
  220. Vector CalcDamageForceVector( const CTakeDamageInfo &info );
  221. virtual int BloodColor();
  222. virtual Activity GetDeathActivity( void );
  223. virtual bool CorpseGib( const CTakeDamageInfo &info );
  224. virtual void CorpseFade( void ); // Called instead of GibNPC() when gibs are disabled
  225. virtual bool HasHumanGibs( void );
  226. virtual bool HasAlienGibs( void );
  227. virtual bool ShouldGib( const CTakeDamageInfo &info ) { return false; } // Always ragdoll, unless specified by the leaf class
  228. float GetDamageAccumulator() { return m_flDamageAccumulator; }
  229. int GetDamageCount( void ) { return m_iDamageCount; } // # of times NPC has been damaged. used for tracking 1-shot kills.
  230. // Character killed (only fired once)
  231. virtual void Event_Killed( const CTakeDamageInfo &info );
  232. // Killed a character
  233. void InputKilledNPC( inputdata_t &inputdata );
  234. virtual void OnKilledNPC( CBaseCombatCharacter *pKilled ) {};
  235. // Exactly one of these happens immediately after killed (gibbed may happen later when the corpse gibs)
  236. // Character gibbed or faded out (violence controls) (only fired once)
  237. // returns true if gibs were spawned
  238. virtual bool Event_Gibbed( const CTakeDamageInfo &info );
  239. // Character entered the dying state without being gibbed (only fired once)
  240. virtual void Event_Dying( const CTakeDamageInfo &info );
  241. virtual void Event_Dying();
  242. // character died and should become a ragdoll now
  243. // return true if converted to a ragdoll, false to use AI death
  244. virtual bool BecomeRagdoll( const CTakeDamageInfo &info, const Vector &forceVector );
  245. virtual void FixupBurningServerRagdoll( CBaseEntity *pRagdoll );
  246. virtual bool BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags );
  247. CBaseEntity *FindHealthItem( const Vector &vecPosition, const Vector &range );
  248. virtual CBaseEntity *CheckTraceHullAttack( float flDist, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float forceScale = 1.0f, bool bDamageAnyNPC = false );
  249. virtual CBaseEntity *CheckTraceHullAttack( const Vector &vStart, const Vector &vEnd, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float flForceScale = 1.0f, bool bDamageAnyNPC = false );
  250. virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return this; }
  251. // VPHYSICS
  252. virtual void VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent );
  253. virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
  254. float CalculatePhysicsStressDamage( vphysics_objectstress_t *pStressOut, IPhysicsObject *pPhysics );
  255. void ApplyStressDamage( IPhysicsObject *pPhysics, bool bRequireLargeObject );
  256. virtual void PushawayTouch( CBaseEntity *pOther ) {}
  257. void SetImpactEnergyScale( float fScale ) { m_impactEnergyScale = fScale; }
  258. virtual void UpdateOnRemove( void );
  259. virtual Disposition_t IRelationType( CBaseEntity *pTarget );
  260. virtual int IRelationPriority( CBaseEntity *pTarget );
  261. virtual void SetLightingOriginRelative( CBaseEntity *pLightingOrigin );
  262. protected:
  263. Relationship_t *FindEntityRelationship( CBaseEntity *pTarget );
  264. public:
  265. // Vehicle queries
  266. virtual bool IsInAVehicle( void ) const { return false; }
  267. virtual IServerVehicle *GetVehicle( void ) { return NULL; }
  268. virtual CBaseEntity *GetVehicleEntity( void ) { return NULL; }
  269. virtual bool ExitVehicle( void ) { return false; }
  270. // Blood color (see BLOOD_COLOR_* macros in baseentity.h)
  271. void SetBloodColor( int nBloodColor );
  272. // Weapons..
  273. CBaseCombatWeapon* GetActiveWeapon() const;
  274. int WeaponCount() const;
  275. CBaseCombatWeapon* GetWeapon( int i ) const;
  276. bool RemoveWeapon( CBaseCombatWeapon *pWeapon );
  277. virtual void RemoveAllWeapons();
  278. WeaponProficiency_t GetCurrentWeaponProficiency() { return m_CurrentWeaponProficiency; }
  279. void SetCurrentWeaponProficiency( WeaponProficiency_t iProficiency ) { m_CurrentWeaponProficiency = iProficiency; }
  280. virtual WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon );
  281. virtual Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
  282. virtual float GetSpreadBias( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget );
  283. virtual void DoMuzzleFlash();
  284. // Interactions
  285. static void InitInteractionSystem();
  286. // Relationships
  287. static void AllocateDefaultRelationships( );
  288. static void SetDefaultRelationship( Class_T nClass, Class_T nClassTarget, Disposition_t nDisposition, int nPriority );
  289. Disposition_t GetDefaultRelationshipDisposition( Class_T nClassTarget );
  290. virtual void AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority );
  291. virtual bool RemoveEntityRelationship( CBaseEntity *pEntity );
  292. virtual void AddClassRelationship( Class_T nClass, Disposition_t nDisposition, int nPriority );
  293. virtual void ChangeTeam( int iTeamNum ) OVERRIDE;
  294. // Nav hull type
  295. Hull_t GetHullType() const { return m_eHull; }
  296. void SetHullType( Hull_t hullType ) { m_eHull = hullType; }
  297. // FIXME: The following 3 methods are backdoor hack methods
  298. // This is a sort of hack back-door only used by physgun!
  299. void SetAmmoCount( int iCount, int iAmmoIndex );
  300. // This is a hack to blat out the current active weapon...
  301. // Used by weapon_slam + game_ui
  302. void SetActiveWeapon( CBaseCombatWeapon *pNewWeapon );
  303. void ClearActiveWeapon() { SetActiveWeapon( NULL ); }
  304. virtual void OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) {}
  305. // I can't use my current weapon anymore. Switch me to the next best weapon.
  306. bool SwitchToNextBestWeapon(CBaseCombatWeapon *pCurrent);
  307. // This is a hack to copy the relationship strings used by monstermaker
  308. void SetRelationshipString( string_t theString ) { m_RelationshipString = theString; }
  309. float GetNextAttack() const { return m_flNextAttack; }
  310. void SetNextAttack( float flWait ) { m_flNextAttack = flWait; }
  311. bool m_bForceServerRagdoll;
  312. // Pickup prevention
  313. bool IsAllowedToPickupWeapons( void ) { return !m_bPreventWeaponPickup; }
  314. void SetPreventWeaponPickup( bool bPrevent ) { m_bPreventWeaponPickup = bPrevent; }
  315. bool m_bPreventWeaponPickup;
  316. virtual CNavArea *GetLastKnownArea( void ) const { return m_lastNavArea; } // return the last nav area the player occupied - NULL if unknown
  317. virtual bool IsAreaTraversable( const CNavArea *area ) const; // return true if we can use the given area
  318. virtual void ClearLastKnownArea( void );
  319. virtual void UpdateLastKnownArea( void ); // invoke this to update our last known nav area (since there is no think method chained to CBaseCombatCharacter)
  320. virtual void OnNavAreaChanged( CNavArea *enteredArea, CNavArea *leftArea ) { } // invoked (by UpdateLastKnownArea) when we enter a new nav area (or it is reset to NULL)
  321. virtual void OnNavAreaRemoved( CNavArea *removedArea );
  322. // -----------------------
  323. // Notification from INextBots.
  324. // -----------------------
  325. virtual void OnPursuedBy( INextBot * RESTRICT pPursuer ){} // called every frame while pursued by a bot in DirectChase.
  326. #ifdef TF_DLL
  327. virtual HalloweenBossType GetBossType() const { return HALLOWEEN_BOSS_INVALID; }
  328. #endif // TF_DLL
  329. #ifdef GLOWS_ENABLE
  330. // Glows
  331. void AddGlowEffect( void );
  332. void RemoveGlowEffect( void );
  333. bool IsGlowEffectActive( void );
  334. #endif // GLOWS_ENABLE
  335. #ifdef INVASION_DLL
  336. public:
  337. // TF2 Powerups
  338. virtual bool CanBePoweredUp( void );
  339. bool HasPowerup( int iPowerup );
  340. virtual bool CanPowerupNow( int iPowerup ); // Return true if I can be powered by this powerup right now
  341. virtual bool CanPowerupEver( int iPowerup ); // Return true if I ever accept this powerup type
  342. void SetPowerup( int iPowerup, bool bState, float flTime = 0, float flAmount = 0, CBaseEntity *pAttacker = NULL, CDamageModifier *pDamageModifier = NULL );
  343. virtual bool AttemptToPowerup( int iPowerup, float flTime, float flAmount = 0, CBaseEntity *pAttacker = NULL, CDamageModifier *pDamageModifier = NULL );
  344. virtual float PowerupDuration( int iPowerup, float flTime );
  345. virtual void PowerupStart( int iPowerup, float flAmount = 0, CBaseEntity *pAttacker = NULL, CDamageModifier *pDamageModifier = NULL );
  346. virtual void PowerupEnd( int iPowerup );
  347. void PowerupThink( void );
  348. virtual void PowerupThink( int iPowerup );
  349. public:
  350. CNetworkVar( int, m_iPowerups );
  351. float m_flPowerupAttemptTimes[ MAX_POWERUPS ];
  352. float m_flPowerupEndTimes[ MAX_POWERUPS ];
  353. float m_flFractionalBoost; // POWERUP_BOOST health fraction - specific powerup data
  354. #endif
  355. public:
  356. // returns the last body region that took damage
  357. int LastHitGroup() const { return m_LastHitGroup; }
  358. protected:
  359. void SetLastHitGroup( int nHitGroup ) { m_LastHitGroup = nHitGroup; }
  360. public:
  361. CNetworkVar( float, m_flNextAttack ); // cannot attack again until this time
  362. #ifdef GLOWS_ENABLE
  363. protected:
  364. CNetworkVar( bool, m_bGlowEnabled );
  365. #endif // GLOWS_ENABLE
  366. private:
  367. Hull_t m_eHull;
  368. void UpdateGlowEffect( void );
  369. void DestroyGlowEffect( void );
  370. protected:
  371. int m_bloodColor; // color of blood particless
  372. // -------------------
  373. // combat ability data
  374. // -------------------
  375. float m_flFieldOfView; // cosine of field of view for this character
  376. Vector m_HackedGunPos; // HACK until we can query end of gun
  377. string_t m_RelationshipString; // Used to load up relationship keyvalues
  378. float m_impactEnergyScale;// scale the amount of energy used to calculate damage this ent takes due to physics
  379. public:
  380. static int GetInteractionID(); // Returns the next interaction #
  381. protected:
  382. // Visibility-related stuff
  383. bool ComputeLOS( const Vector &vecEyePosition, const Vector &vecTarget ) const;
  384. private:
  385. // For weapon strip
  386. void ThrowDirForWeaponStrip( CBaseCombatWeapon *pWeapon, const Vector &vecForward, Vector *pVecThrowDir );
  387. void DropWeaponForWeaponStrip( CBaseCombatWeapon *pWeapon, const Vector &vecForward, const QAngle &vecAngles, float flDiameter );
  388. friend class CScriptedTarget; // needs to access GetInteractionID()
  389. static int m_lastInteraction; // Last registered interaction #
  390. static Relationship_t** m_DefaultRelationship;
  391. // attack/damage
  392. int m_LastHitGroup; // the last body region that took damage
  393. float m_flDamageAccumulator; // so very small amounts of damage do not get lost.
  394. int m_iDamageCount; // # of times NPC has been damaged. used for tracking 1-shot kills.
  395. // Weapon proficiency gets calculated each time an NPC changes his weapon, and then
  396. // cached off as the CurrentWeaponProficiency.
  397. WeaponProficiency_t m_CurrentWeaponProficiency;
  398. // ---------------
  399. // Relationships
  400. // ---------------
  401. CUtlVector<Relationship_t> m_Relationship; // Array of relationships
  402. protected:
  403. // shared ammo slots
  404. CNetworkArrayForDerived( int, m_iAmmo, MAX_AMMO_SLOTS );
  405. // Usable character items
  406. CNetworkArray( CBaseCombatWeaponHandle, m_hMyWeapons, MAX_WEAPONS );
  407. CNetworkHandle( CBaseCombatWeapon, m_hActiveWeapon );
  408. friend class CCleanupDefaultRelationShips;
  409. IntervalTimer m_aliveTimer;
  410. unsigned int m_hasBeenInjured; // bitfield corresponding to team ID that did the injury
  411. // we do this because MAX_TEAMS is 32, which is wasteful for most games
  412. enum { MAX_DAMAGE_TEAMS = 4 };
  413. struct DamageHistory
  414. {
  415. int team; // which team hurt us (TEAM_INVALID means slot unused)
  416. IntervalTimer interval; // how long has it been
  417. };
  418. DamageHistory m_damageHistory[ MAX_DAMAGE_TEAMS ];
  419. // last known navigation area of player - NULL if unknown
  420. CNavArea *m_lastNavArea;
  421. CAI_MoveMonitor m_NavAreaUpdateMonitor;
  422. int m_registeredNavTeam; // ugly, but needed to clean up player team counts in nav mesh
  423. };
  424. inline float CBaseCombatCharacter::GetAliveDuration( void ) const
  425. {
  426. return m_aliveTimer.GetElapsedTime();
  427. }
  428. //-----------------------------------------------------------------------------
  429. // Purpose:
  430. //-----------------------------------------------------------------------------
  431. inline int CBaseCombatCharacter::WeaponCount() const
  432. {
  433. return MAX_WEAPONS;
  434. }
  435. //-----------------------------------------------------------------------------
  436. // Purpose:
  437. // Input : i -
  438. //-----------------------------------------------------------------------------
  439. inline CBaseCombatWeapon *CBaseCombatCharacter::GetWeapon( int i ) const
  440. {
  441. Assert( (i >= 0) && (i < MAX_WEAPONS) );
  442. return m_hMyWeapons[i].Get();
  443. }
  444. #ifdef INVASION_DLL
  445. // Powerup Inlines
  446. inline bool CBaseCombatCharacter::CanBePoweredUp( void ) { return true; }
  447. inline float CBaseCombatCharacter::PowerupDuration( int iPowerup, float flTime ) { return flTime; }
  448. inline void CBaseCombatCharacter::PowerupEnd( int iPowerup ) { return; }
  449. inline void CBaseCombatCharacter::PowerupThink( int iPowerup ) { return; }
  450. #endif
  451. EXTERN_SEND_TABLE(DT_BaseCombatCharacter);
  452. void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore );
  453. //-----------------------------------------------------------------------------
  454. // Purpose:
  455. //-----------------------------------------------------------------------------
  456. class CTraceFilterMelee : public CTraceFilterEntitiesOnly
  457. {
  458. public:
  459. // It does have a base, but we'll never network anything below here..
  460. DECLARE_CLASS_NOBASE( CTraceFilterMelee );
  461. CTraceFilterMelee( const IHandleEntity *passentity, int collisionGroup, CTakeDamageInfo *dmgInfo, float flForceScale, bool bDamageAnyNPC )
  462. : m_pPassEnt(passentity), m_collisionGroup(collisionGroup), m_dmgInfo(dmgInfo), m_pHit(NULL), m_flForceScale(flForceScale), m_bDamageAnyNPC(bDamageAnyNPC)
  463. {
  464. }
  465. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  466. public:
  467. const IHandleEntity *m_pPassEnt;
  468. int m_collisionGroup;
  469. CTakeDamageInfo *m_dmgInfo;
  470. CBaseEntity *m_pHit;
  471. float m_flForceScale;
  472. bool m_bDamageAnyNPC;
  473. };
  474. #endif // BASECOMBATCHARACTER_H