Counter Strike : Global Offensive Source Code
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.

607 lines
27 KiB

  1. //===== Copyright � 1996-2005, 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. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "baseflex.h"
  13. #include "damagemodifier.h"
  14. #include "utllinkedlist.h"
  15. #include "ai_hull.h"
  16. #include "ai_utils.h"
  17. #include "physics_impact_damage.h"
  18. #include <limits.h>
  19. #include "weapon_proficiency.h"
  20. #if defined( PORTAL2 )
  21. // HACK, Should come from game specific enum...
  22. #include "weapons_portal.h"
  23. #elif defined( CSTRIKE_DLL )
  24. #include "cs_weapon_parse.h"
  25. #else
  26. #define WEAPON_MAX 32
  27. #endif
  28. class CScriptedTarget;
  29. typedef CHandle<CBaseCombatWeapon> CBaseCombatWeaponHandle;
  30. struct fogparams_t;
  31. class CNavArea;
  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_CRAWL = 0x00000010, // crawl
  42. bits_CAP_MOVE_SWIM = 0x00000020, // navigate in water // 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_NO_LOCAL_NAV_CRAWL = 0x00000200, // Don't try to crawl when doing local navigation
  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. #define bits_CAP_MOVE_GROUP (bits_CAP_MOVE_GROUND | bits_CAP_MOVE_JUMP | bits_CAP_MOVE_FLY | bits_CAP_MOVE_CLIMB | bits_CAP_MOVE_CRAWL | bits_CAP_MOVE_SWIM)
  74. class CBaseCombatWeapon;
  75. #define BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE 0.9f
  76. enum Disposition_t
  77. {
  78. D_ER, // Undefined - error
  79. D_HT, // Hate
  80. D_FR, // Fear
  81. D_LI, // Like
  82. D_NU, // Neutral
  83. // The following are duplicates of the above, only with friendlier names
  84. D_ERROR = D_ER, // Undefined - error
  85. D_HATE = D_HT, // Hate
  86. D_FEAR = D_FR, // Fear
  87. D_LIKE = D_LI, // Like
  88. D_NEUTRAL = D_NU, // Neutral
  89. };
  90. const int DEF_RELATIONSHIP_PRIORITY = INT_MIN;
  91. struct Relationship_t
  92. {
  93. EHANDLE entity; // Relationship to a particular entity
  94. Class_T classType; // Relationship to a class CLASS_NONE = not class based (Def. in baseentity.h)
  95. int faction; // Relationship to a faction FACTION_NONE = not faction based
  96. Disposition_t disposition; // D_HT (Hate), D_FR (Fear), D_LI (Like), D_NT (Neutral)
  97. int priority; // Relative importance of this relationship (higher numbers mean more important)
  98. DECLARE_SIMPLE_DATADESC();
  99. };
  100. //-----------------------------------------------------------------------------
  101. // Purpose: This should contain all of the combat entry points / functionality
  102. // that are common between NPCs and players
  103. //-----------------------------------------------------------------------------
  104. class CBaseCombatCharacter : public CBaseFlex
  105. {
  106. DECLARE_CLASS( CBaseCombatCharacter, CBaseFlex );
  107. public:
  108. CBaseCombatCharacter(void);
  109. ~CBaseCombatCharacter(void);
  110. DECLARE_SERVERCLASS();
  111. DECLARE_DATADESC();
  112. DECLARE_PREDICTABLE();
  113. public:
  114. virtual void Spawn( void );
  115. virtual void Precache();
  116. virtual int Restore( IRestore &restore );
  117. virtual const impactdamagetable_t &GetPhysicsImpactDamageTable( void );
  118. int TakeHealth( float flHealth, int bitsDamageType );
  119. void CauseDeath( const CTakeDamageInfo &info );
  120. virtual bool FVisible ( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); // true iff the parameter can be seen by me.
  121. virtual bool FVisible( const Vector &vecTarget, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ) { return BaseClass::FVisible( vecTarget, traceMask, ppBlocker ); }
  122. static void ResetVisibilityCache( CBaseCombatCharacter *pBCC = NULL );
  123. #ifdef PORTAL
  124. virtual bool FVisibleThroughPortal( const CPortal_Base2D *pPortal, CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL );
  125. #endif
  126. virtual bool FInViewCone( CBaseEntity *pEntity );
  127. virtual bool FInViewCone( const Vector &vecSpot );
  128. #ifdef PORTAL
  129. virtual CPortal_Base2D* FInViewConeThroughPortal( CBaseEntity *pEntity );
  130. virtual CPortal_Base2D* FInViewConeThroughPortal( const Vector &vecSpot );
  131. #endif
  132. virtual bool FInAimCone( CBaseEntity *pEntity );
  133. virtual bool FInAimCone( const Vector &vecSpot );
  134. virtual bool ShouldShootMissTarget( CBaseCombatCharacter *pAttacker );
  135. virtual CBaseEntity *FindMissTarget( void );
  136. // Do not call HandleInteraction directly, use DispatchInteraction
  137. bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return ( interactionType > 0 ) ? HandleInteraction( interactionType, data, sourceEnt ) : false; }
  138. virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt );
  139. virtual QAngle BodyAngles();
  140. virtual Vector BodyDirection2D( void );
  141. virtual Vector BodyDirection3D( void );
  142. virtual Vector HeadDirection2D( void ) { return BodyDirection2D( ); }; // No head motion so just return body dir
  143. virtual Vector HeadDirection3D( void ) { return BodyDirection2D( ); }; // No head motion so just return body dir
  144. virtual Vector EyeDirection2D( void ) { return HeadDirection2D( ); }; // No eye motion so just return head dir
  145. virtual Vector EyeDirection3D( void ) { return HeadDirection3D( ); }; // No eye motion so just return head dir
  146. virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
  147. // -----------------------
  148. // Fog
  149. // -----------------------
  150. void OnFogTriggerStartTouch( CBaseEntity *fogTrigger );
  151. void OnFogTriggerEndTouch( CBaseEntity *fogTrigger );
  152. CBaseEntity * GetFogTrigger( void );
  153. virtual bool IsHiddenByFog( const Vector &target ) const; ///< return true if given target cant be seen because of fog
  154. virtual bool IsHiddenByFog( CBaseEntity *target ) const; ///< return true if given target cant be seen because of fog
  155. virtual bool IsHiddenByFog( float range ) const; ///< return true if given distance is too far to see through the fog
  156. virtual float GetFogObscuredRatio( const Vector &target ) const;///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
  157. virtual float GetFogObscuredRatio( CBaseEntity *target ) const; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
  158. virtual float GetFogObscuredRatio( float range ) const; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
  159. virtual bool GetFogParams( fogparams_t *fog ) const; ///< return the current fog parameters
  160. // -----------------------
  161. // Vision
  162. // -----------------------
  163. enum FieldOfViewCheckType { USE_FOV, DISREGARD_FOV };
  164. // Visible starts with line of sight, and adds all the extra game checks like fog, smoke, camo...
  165. bool IsAbleToSee( const CBaseEntity *entity, FieldOfViewCheckType checkFOV );
  166. bool IsAbleToSee( CBaseCombatCharacter *pBCC, FieldOfViewCheckType checkFOV );
  167. 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.
  168. 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.
  169. virtual bool IsInFieldOfView( CBaseEntity *entity ) const; // Calls IsLookingTowards with the current field of view.
  170. virtual bool IsInFieldOfView( const Vector &pos ) const;
  171. enum LineOfSightCheckType
  172. {
  173. IGNORE_NOTHING,
  174. IGNORE_ACTORS
  175. };
  176. virtual bool IsLineOfSightClear( CBaseEntity *entity, LineOfSightCheckType checkType = IGNORE_NOTHING ) const;// strictly LOS check with no other considerations
  177. virtual bool IsLineOfSightClear( const Vector &pos, LineOfSightCheckType checkType = IGNORE_NOTHING, CBaseEntity *entityToIgnore = NULL ) const;
  178. // -----------------------
  179. // Footsteps
  180. // -----------------------
  181. void PlayFootstepSound( const Vector& origin, bool leftFoot, bool feetInWater, bool kneesInWater, bool jumping = false );
  182. virtual void OnFootstep( const Vector& origin, bool leftFoot, bool feetInWater, bool kneesInWater, bool jumping ) {}
  183. // -----------------------
  184. // Ammo
  185. // -----------------------
  186. virtual int GiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound = false );
  187. int GiveAmmo( int iCount, const char *szName, bool bSuppressSound = false );
  188. void RemoveAmmo( int iCount, int iAmmoIndex );
  189. void RemoveAmmo( int iCount, const char *szName );
  190. void RemoveAllAmmo( );
  191. int GetAmmoCount( int iAmmoIndex ) const;
  192. int GetAmmoCount( char *szName ) const;
  193. virtual Activity NPC_TranslateActivity( Activity baseAct );
  194. // -----------------------
  195. // Weapons
  196. // -----------------------
  197. CBaseCombatWeapon* Weapon_Create( const char *pWeaponName );
  198. virtual Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL );
  199. void Weapon_SetActivity( Activity newActivity, float duration );
  200. virtual void Weapon_FrameUpdate( void );
  201. virtual void Weapon_HandleAnimEvent( animevent_t *pEvent );
  202. virtual CBaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class
  203. virtual bool Weapon_CanUse( CBaseCombatWeapon *pWeapon ); // True is allowed to use this class of weapon
  204. virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon ); // Adds weapon to player
  205. virtual bool Weapon_EquipAmmoOnly( CBaseCombatWeapon *pWeapon ); // Adds weapon ammo to player, leaves weapon
  206. bool Weapon_Detach( CBaseCombatWeapon *pWeapon ); // Clear any pointers to the weapon.
  207. virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget = NULL, const Vector *pVelocity = NULL );
  208. virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed)
  209. virtual Vector Weapon_ShootPosition( ); // gun position at current position/orientation
  210. bool Weapon_IsOnGround( CBaseCombatWeapon *pWeapon );
  211. CBaseEntity* Weapon_FindUsable( const Vector &range ); // search for a usable weapon in this range
  212. virtual bool Weapon_CanSwitchTo(CBaseCombatWeapon *pWeapon);
  213. virtual bool Weapon_SlotOccupied( CBaseCombatWeapon *pWeapon );
  214. virtual CBaseCombatWeapon *Weapon_GetSlot( int slot ) const;
  215. virtual CBaseCombatWeapon *Weapon_GetPosition( int pos ) const;
  216. CBaseCombatWeapon *Weapon_GetWpnForAmmo( int iAmmoIndex );
  217. virtual bool ShouldPickupItemSilently( CBaseCombatCharacter *pNewOwner ) { return false; }
  218. // For weapon strip
  219. void Weapon_DropAll( bool bDisallowWeaponPickup = false );
  220. virtual bool AddPlayerItem( CBaseCombatWeapon *pItem ) { return false; }
  221. virtual bool RemovePlayerItem( CBaseCombatWeapon *pItem ) { return false; }
  222. virtual bool CanBecomeServerRagdoll( void ) { return true; }
  223. // -----------------------
  224. // Damage
  225. // -----------------------
  226. // Don't override this for characters, override the per-life-state versions below
  227. virtual int OnTakeDamage( const CTakeDamageInfo &info );
  228. // Override these to control how your character takes damage in different states
  229. virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info );
  230. virtual int OnTakeDamage_Dying( const CTakeDamageInfo &info );
  231. virtual int OnTakeDamage_Dead( const CTakeDamageInfo &info );
  232. virtual float GetAliveDuration( void ) const; // return time we have been alive (only valid when alive)
  233. virtual void OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker ) {}
  234. virtual void NotifyFriendsOfDamage( CBaseEntity *pAttackerEntity ) {}
  235. virtual bool HasEverBeenInjured( int team = TEAM_ANY ) const; // return true if we have ever been injured by a member of the given team
  236. virtual float GetTimeSinceLastInjury( int team = TEAM_ANY ) const; // return time since we were hurt by a member of the given team
  237. RelativeDamagedDirection_t GetLastInjuryRelativeDirection( void ) { return m_nRelativeDirectionOfLastInjury; }
  238. uint32 GetLastDamageTypeFlags( void ) const { return m_uiLastDamageTypeFlags; }
  239. virtual void OnPlayerKilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) {}
  240. // utility function to calc damage force
  241. virtual Vector CalcDeathForceVector( const CTakeDamageInfo &info );
  242. virtual int BloodColor();
  243. virtual Activity GetDeathActivity( void );
  244. virtual bool CorpseGib( const CTakeDamageInfo &info );
  245. virtual void CorpseFade( void ); // Called instead of GibNPC() when gibs are disabled
  246. virtual bool HasHumanGibs( void );
  247. virtual bool HasAlienGibs( void );
  248. virtual bool ShouldGib( const CTakeDamageInfo &info ) { return false; } // Always ragdoll, unless specified by the leaf class
  249. float GetDamageAccumulator() { return m_flDamageAccumulator; }
  250. int GetDamageCount( void ) { return m_iDamageCount; } // # of times NPC has been damaged. used for tracking 1-shot kills.
  251. // Character killed (only fired once)
  252. virtual void Event_Killed( const CTakeDamageInfo &info );
  253. virtual bool ShouldDropActiveWeaponWhenKilled() { return true; }
  254. // Killed a character
  255. void InputKilledNPC( inputdata_t &inputdata );
  256. virtual void OnKilledNPC( CBaseCombatCharacter *pKilled ) {};
  257. // Exactly one of these happens immediately after killed (gibbed may happen later when the corpse gibs)
  258. // Character gibbed or faded out (violence controls) (only fired once)
  259. // returns true if gibs were spawned
  260. virtual bool Event_Gibbed( const CTakeDamageInfo &info );
  261. // Character entered the dying state without being gibbed (only fired once)
  262. virtual void Event_Dying( void );
  263. // character died and should become a ragdoll now
  264. // return true if converted to a ragdoll, false to use AI death
  265. virtual bool BecomeRagdoll( const CTakeDamageInfo &info, const Vector &forceVector );
  266. virtual void FixupBurningServerRagdoll( CBaseEntity *pRagdoll );
  267. virtual bool BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags );
  268. CBaseEntity *FindHealthItem( const Vector &vecPosition, const Vector &range );
  269. virtual CBaseEntity *CheckTraceHullAttack( float flDist, const Vector &mins, const Vector &maxs, float flDamage, int iDmgType, float forceScale = 1.0f, bool bDamageAnyNPC = false );
  270. virtual CBaseEntity *CheckTraceHullAttack( const Vector &vStart, const Vector &vEnd, const Vector &mins, const Vector &maxs, float flDamage, int iDmgType, float flForceScale = 1.0f, bool bDamageAnyNPC = false );
  271. virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return this; }
  272. // VPHYSICS
  273. virtual void VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent );
  274. #if !defined( PORTAL2 )
  275. virtual void VPhysicsUpdate( IPhysicsObject *pPhysics );
  276. #endif
  277. float CalculatePhysicsStressDamage( vphysics_objectstress_t *pStressOut, IPhysicsObject *pPhysics );
  278. void ApplyStressDamage( IPhysicsObject *pPhysics, bool bRequireLargeObject );
  279. virtual void PushawayTouch( CBaseEntity *pOther ) {}
  280. void SetImpactEnergyScale( float fScale ) { m_impactEnergyScale = fScale; }
  281. virtual void UpdateOnRemove( void );
  282. virtual Disposition_t IRelationType( CBaseEntity *pTarget );
  283. virtual int IRelationPriority( CBaseEntity *pTarget );
  284. virtual void SetLightingOriginRelative( CBaseEntity *pLightingOrigin );
  285. protected:
  286. Relationship_t *FindEntityRelationship( CBaseEntity *pTarget );
  287. public:
  288. // Vehicle queries
  289. virtual bool IsInAVehicle( void ) const { return false; }
  290. virtual IServerVehicle *GetVehicle( void ) { return NULL; }
  291. virtual CBaseEntity *GetVehicleEntity( void ) { return NULL; }
  292. virtual bool ExitVehicle( void ) { return false; }
  293. // Blood color (see BLOOD_COLOR_* macros in baseentity.h)
  294. void SetBloodColor( int nBloodColor );
  295. // Weapons..
  296. CBaseCombatWeapon* GetActiveWeapon() const;
  297. int WeaponCount() const;
  298. CBaseCombatWeapon* GetWeapon( int i ) const;
  299. bool RemoveWeapon( CBaseCombatWeapon *pWeapon );
  300. virtual void RemoveAllWeapons();
  301. virtual void RemoveAllWearables( void );
  302. virtual void RemoveWeaponOnPlayer( CBaseCombatWeapon *pWeapon );
  303. WeaponProficiency_t GetCurrentWeaponProficiency() { return m_CurrentWeaponProficiency; }
  304. void SetCurrentWeaponProficiency( WeaponProficiency_t iProficiency ) { m_CurrentWeaponProficiency = iProficiency; }
  305. virtual WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon );
  306. virtual Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL );
  307. virtual float GetSpreadBias( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget );
  308. virtual void DoMuzzleFlash();
  309. // Interactions
  310. static void InitInteractionSystem();
  311. // Relationships
  312. static void SetDefaultFactionRelationship(int nFaction, int nFactionTarget, Disposition_t nDisposition, int nPriority);
  313. Disposition_t GetFactionRelationshipDisposition( int nFaction );
  314. static void AllocateDefaultRelationships( );
  315. static void AllocateDefaultFactionRelationships( );
  316. static void SetDefaultRelationship( Class_T nClass, Class_T nClassTarget, Disposition_t nDisposition, int nPriority );
  317. Disposition_t GetDefaultRelationshipDisposition( Class_T nClassTarget );
  318. virtual void AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority );
  319. virtual bool RemoveEntityRelationship( CBaseEntity *pEntity );
  320. virtual void AddClassRelationship( Class_T nClass, Disposition_t nDisposition, int nPriority );
  321. virtual void AddFactionRelationship(int nFaction, Disposition_t nDisposition, int nPriority);
  322. // Factions
  323. static int GetNumFactions( void );
  324. static CUtlVector<EHANDLE> *GetEntitiesInFaction( int nFaction );
  325. int GetFaction( void ) const { return m_nFaction; }
  326. virtual void ChangeFaction( int nNewFaction );
  327. virtual void ChangeTeam( int iTeamNum );
  328. // Nav hull type
  329. Hull_t GetHullType() const { return m_eHull; }
  330. void SetHullType( Hull_t hullType ) { m_eHull = hullType; }
  331. // FIXME: The following 3 methods are backdoor hack methods
  332. // This is a sort of hack back-door only used by physgun!
  333. void SetAmmoCount( int iCount, int iAmmoIndex );
  334. // This is a hack to blat out the current active weapon...
  335. // Used by weapon_slam + game_ui
  336. void SetActiveWeapon( CBaseCombatWeapon *pNewWeapon );
  337. void ClearActiveWeapon() { SetActiveWeapon( NULL ); }
  338. virtual void OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) {}
  339. // I can't use my current weapon anymore. Switch me to the next best weapon.
  340. bool SwitchToNextBestWeapon(CBaseCombatWeapon *pCurrent);
  341. // This is a hack to copy the relationship strings used by monstermaker
  342. void SetRelationshipString( string_t theString ) { m_RelationshipString = theString; }
  343. float GetNextAttack() const { return m_flNextAttack; }
  344. void SetNextAttack( float flWait ) { m_flNextAttack = flWait; }
  345. bool m_bForceServerRagdoll;
  346. // Pickup prevention
  347. bool IsAllowedToPickupWeapons( void ) { return !m_bPreventWeaponPickup; }
  348. void SetPreventWeaponPickup( bool bPrevent ) { m_bPreventWeaponPickup = bPrevent; }
  349. bool m_bPreventWeaponPickup;
  350. virtual CNavArea *GetLastKnownArea( void ) const { return m_lastNavArea; } // return the last nav area the player occupied - NULL if unknown
  351. virtual bool IsAreaTraversable( const CNavArea *area ) const; // return true if we can use the given area
  352. virtual void ClearLastKnownArea( void );
  353. virtual void UpdateLastKnownArea( void ); // invoke this to update our last known nav area (since there is no think method chained to CBaseCombatCharacter)
  354. virtual void OnNavAreaChanged( CNavArea *enteredArea, CNavArea *leftArea ) { } // invoked (by UpdateLastKnownArea) when we enter a new nav area (or it is reset to NULL)
  355. virtual void OnNavAreaRemoved( CNavArea *removedArea );
  356. // -----------------------
  357. // Notification from INextBots.
  358. // -----------------------
  359. virtual void OnPursuedBy( INextBot * RESTRICT pPursuer ){} // called every frame while pursued by a bot in DirectChase.
  360. public:
  361. // returns the last body region that took damage
  362. int LastHitGroup() const { return m_LastHitGroup; }
  363. protected:
  364. void SetLastHitGroup( int nHitGroup ) { m_LastHitGroup = nHitGroup; }
  365. public:
  366. CNetworkVar( float, m_flNextAttack ); // cannot attack again until this time
  367. private:
  368. Hull_t m_eHull;
  369. protected:
  370. int m_bloodColor; // color of blood particless
  371. // -------------------
  372. // combat ability data
  373. // -------------------
  374. float m_flFieldOfView; // cosine of field of view for this character
  375. Vector m_HackedGunPos; // HACK until we can query end of gun
  376. string_t m_RelationshipString; // Used to load up relationship keyvalues
  377. float m_impactEnergyScale;// scale the amount of energy used to calculate damage this ent takes due to physics
  378. byte m_weaponIDToIndex[WEAPON_MAX];
  379. public:
  380. static int GetInteractionID(); // Returns the next interaction #
  381. float GetTimeOfLastInjury( void ) const { return m_flTimeOfLastInjury; };
  382. protected:
  383. // Visibility-related stuff
  384. bool ComputeLOS( const Vector &vecEyePosition, const Vector &vecTarget ) const;
  385. private:
  386. bool ComputeTargetIsInDarkness( const Vector &vecEyePosition, CNavArea *pTargetNavArea, const Vector &vecTargetPos ) const;
  387. protected:
  388. // For weapon strip
  389. void ThrowDirForWeaponStrip( CBaseCombatWeapon *pWeapon, const Vector &vecForward, Vector *pVecThrowDir );
  390. void DropWeaponForWeaponStrip( CBaseCombatWeapon *pWeapon, const Vector &vecForward, const QAngle &vecAngles, float flDiameter );
  391. protected:
  392. friend class CScriptedTarget; // needs to access GetInteractionID()
  393. static int m_lastInteraction; // Last registered interaction #
  394. static Relationship_t** m_DefaultRelationship;
  395. static Relationship_t** m_FactionRelationship;
  396. static CUtlVector< CUtlVector< EHANDLE> > m_aFactions;
  397. public:
  398. // attack/damage
  399. CNetworkVar( int, m_LastHitGroup ); // the last body region that took damage
  400. private:
  401. float m_flDamageAccumulator; // so very small amounts of damage do not get lost.
  402. int m_iDamageCount; // # of times NPC has been damaged. used for tracking 1-shot kills.
  403. // Weapon proficiency gets calculated each time an NPC changes his weapon, and then
  404. // cached off as the CurrentWeaponProficiency.
  405. WeaponProficiency_t m_CurrentWeaponProficiency;
  406. // ---------------
  407. // Relationships
  408. // ---------------
  409. CUtlVector<Relationship_t> m_Relationship; // Array of relationships
  410. int m_nFaction;
  411. // Used by trigger_fog to manage when the character is touching multiple fog triggers simultaneously.
  412. // The one at the HEAD of the list is always the current fog trigger for the character.
  413. CUtlVector<EHANDLE> m_hTriggerFogList;
  414. EHANDLE m_hLastFogTrigger;
  415. protected:
  416. // shared ammo slots
  417. CNetworkArrayForDerived( int, m_iAmmo, MAX_AMMO_TYPES );
  418. // Usable character items
  419. CNetworkArray( CBaseCombatWeaponHandle, m_hMyWeapons, MAX_WEAPONS );
  420. CNetworkHandle( CBaseCombatWeapon, m_hActiveWeapon );
  421. IntervalTimer m_aliveTimer;
  422. unsigned int m_hasBeenInjured; // bitfield corresponding to team ID that did the injury
  423. // we do this because MAX_TEAMS is 32, which is wasteful for most games
  424. enum { MAX_DAMAGE_TEAMS = 4 };
  425. struct DamageHistory
  426. {
  427. int team; // which team hurt us (TEAM_INVALID means slot unused)
  428. IntervalTimer interval; // how long has it been
  429. };
  430. DamageHistory m_damageHistory[ MAX_DAMAGE_TEAMS ];
  431. CNetworkVar( float, m_flTimeOfLastInjury );
  432. CNetworkVar( RelativeDamagedDirection_t, m_nRelativeDirectionOfLastInjury );
  433. // CNetworkVar( uint32, m_uiLastDamageTypeFlags );
  434. uint32 m_uiLastDamageTypeFlags;
  435. // last known navigation area of player - NULL if unknown
  436. CNavArea *m_lastNavArea;
  437. CAI_MoveMonitor m_NavAreaUpdateMonitor;
  438. int m_registeredNavTeam; // ugly, but needed to clean up player team counts in nav mesh
  439. friend class CCleanupDefaultRelationShips;
  440. };
  441. inline float CBaseCombatCharacter::GetAliveDuration( void ) const
  442. {
  443. return m_aliveTimer.GetElapsedTime();
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Purpose:
  447. //-----------------------------------------------------------------------------
  448. inline int CBaseCombatCharacter::WeaponCount() const
  449. {
  450. return MAX_WEAPONS;
  451. }
  452. EXTERN_SEND_TABLE(DT_BaseCombatCharacter);
  453. void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore );
  454. //-----------------------------------------------------------------------------
  455. // Purpose:
  456. //-----------------------------------------------------------------------------
  457. class CTraceFilterMelee : public CTraceFilterEntitiesOnly
  458. {
  459. public:
  460. // It does have a base, but we'll never network anything below here..
  461. DECLARE_CLASS_NOBASE( CTraceFilterMelee );
  462. CTraceFilterMelee( const IHandleEntity *passentity, int collisionGroup, CTakeDamageInfo *dmgInfo, float flForceScale, bool bDamageAnyNPC )
  463. : m_pPassEnt(passentity), m_collisionGroup(collisionGroup), m_dmgInfo(dmgInfo), m_pHit(NULL), m_flForceScale(flForceScale), m_bDamageAnyNPC(bDamageAnyNPC)
  464. {
  465. }
  466. virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask );
  467. public:
  468. const IHandleEntity *m_pPassEnt;
  469. int m_collisionGroup;
  470. CTakeDamageInfo *m_dmgInfo;
  471. CBaseEntity *m_pHit;
  472. float m_flForceScale;
  473. bool m_bDamageAnyNPC;
  474. };
  475. #endif // BASECOMBATCHARACTER_H