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
610 lines
26 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Base combat character with no AI |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef BASECOMBATCHARACTER_H |
|
#define BASECOMBATCHARACTER_H |
|
|
|
#include <limits.h> |
|
#include "weapon_proficiency.h" |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#ifdef INVASION_DLL |
|
#include "tf_shareddefs.h" |
|
|
|
#define POWERUP_THINK_CONTEXT "PowerupThink" |
|
#endif |
|
|
|
#include "cbase.h" |
|
#include "baseentity.h" |
|
#include "baseflex.h" |
|
#include "damagemodifier.h" |
|
#include "utllinkedlist.h" |
|
#include "ai_hull.h" |
|
#include "ai_utils.h" |
|
#include "physics_impact_damage.h" |
|
|
|
class CNavArea; |
|
class CScriptedTarget; |
|
typedef CHandle<CBaseCombatWeapon> CBaseCombatWeaponHandle; |
|
|
|
// ------------------------------------- |
|
// Capability Bits |
|
// ------------------------------------- |
|
|
|
enum Capability_t |
|
{ |
|
bits_CAP_MOVE_GROUND = 0x00000001, // walk/run |
|
bits_CAP_MOVE_JUMP = 0x00000002, // jump/leap |
|
bits_CAP_MOVE_FLY = 0x00000004, // can fly, move all around |
|
bits_CAP_MOVE_CLIMB = 0x00000008, // climb ladders |
|
bits_CAP_MOVE_SWIM = 0x00000010, // navigate in water // UNDONE - not yet implemented |
|
bits_CAP_MOVE_CRAWL = 0x00000020, // crawl // UNDONE - not yet implemented |
|
bits_CAP_MOVE_SHOOT = 0x00000040, // tries to shoot weapon while moving |
|
bits_CAP_SKIP_NAV_GROUND_CHECK = 0x00000080, // optimization - skips ground tests while computing navigation |
|
bits_CAP_USE = 0x00000100, // open doors/push buttons/pull levers |
|
//bits_CAP_HEAR = 0x00000200, // can hear forced sounds |
|
bits_CAP_AUTO_DOORS = 0x00000400, // can trigger auto doors |
|
bits_CAP_OPEN_DOORS = 0x00000800, // can open manual doors |
|
bits_CAP_TURN_HEAD = 0x00001000, // can turn head, always bone controller 0 |
|
bits_CAP_WEAPON_RANGE_ATTACK1 = 0x00002000, // can do a weapon range attack 1 |
|
bits_CAP_WEAPON_RANGE_ATTACK2 = 0x00004000, // can do a weapon range attack 2 |
|
bits_CAP_WEAPON_MELEE_ATTACK1 = 0x00008000, // can do a weapon melee attack 1 |
|
bits_CAP_WEAPON_MELEE_ATTACK2 = 0x00010000, // can do a weapon melee attack 2 |
|
bits_CAP_INNATE_RANGE_ATTACK1 = 0x00020000, // can do a innate range attack 1 |
|
bits_CAP_INNATE_RANGE_ATTACK2 = 0x00040000, // can do a innate range attack 1 |
|
bits_CAP_INNATE_MELEE_ATTACK1 = 0x00080000, // can do a innate melee attack 1 |
|
bits_CAP_INNATE_MELEE_ATTACK2 = 0x00100000, // can do a innate melee attack 1 |
|
bits_CAP_USE_WEAPONS = 0x00200000, // can use weapons (non-innate attacks) |
|
//bits_CAP_STRAFE = 0x00400000, // strafe ( walk/run sideways) |
|
bits_CAP_ANIMATEDFACE = 0x00800000, // has animated eyes/face |
|
bits_CAP_USE_SHOT_REGULATOR = 0x01000000, // Uses the shot regulator for range attack1 |
|
bits_CAP_FRIENDLY_DMG_IMMUNE = 0x02000000, // don't take damage from npc's that are D_LI |
|
bits_CAP_SQUAD = 0x04000000, // can form squads |
|
bits_CAP_DUCK = 0x08000000, // cover and reload ducking |
|
bits_CAP_NO_HIT_PLAYER = 0x10000000, // don't hit players |
|
bits_CAP_AIM_GUN = 0x20000000, // Use arms to aim gun, not just body |
|
bits_CAP_NO_HIT_SQUADMATES = 0x40000000, // none |
|
bits_CAP_SIMPLE_RADIUS_DAMAGE = 0x80000000, // Do not use robust radius damage model on this character. |
|
}; |
|
|
|
#define bits_CAP_DOORS_GROUP (bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS) |
|
#define bits_CAP_RANGE_ATTACK_GROUP (bits_CAP_WEAPON_RANGE_ATTACK1 | bits_CAP_WEAPON_RANGE_ATTACK2) |
|
#define bits_CAP_MELEE_ATTACK_GROUP (bits_CAP_WEAPON_MELEE_ATTACK1 | bits_CAP_WEAPON_MELEE_ATTACK2) |
|
|
|
|
|
class CBaseCombatWeapon; |
|
|
|
#define BCC_DEFAULT_LOOK_TOWARDS_TOLERANCE 0.9f |
|
|
|
enum Disposition_t |
|
{ |
|
D_ER, // Undefined - error |
|
D_HT, // Hate |
|
D_FR, // Fear |
|
D_LI, // Like |
|
D_NU // Neutral |
|
}; |
|
|
|
const int DEF_RELATIONSHIP_PRIORITY = INT_MIN; |
|
|
|
struct Relationship_t |
|
{ |
|
EHANDLE entity; // Relationship to a particular entity |
|
Class_T classType; // Relationship to a class CLASS_NONE = not class based (Def. in baseentity.h) |
|
Disposition_t disposition; // D_HT (Hate), D_FR (Fear), D_LI (Like), D_NT (Neutral) |
|
int priority; // Relative importance of this relationship (higher numbers mean more important) |
|
|
|
DECLARE_SIMPLE_DATADESC(); |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: This should contain all of the combat entry points / functionality |
|
// that are common between NPCs and players |
|
//----------------------------------------------------------------------------- |
|
class CBaseCombatCharacter : public CBaseFlex |
|
{ |
|
DECLARE_CLASS( CBaseCombatCharacter, CBaseFlex ); |
|
|
|
public: |
|
CBaseCombatCharacter(void); |
|
~CBaseCombatCharacter(void); |
|
|
|
DECLARE_SERVERCLASS(); |
|
DECLARE_DATADESC(); |
|
DECLARE_PREDICTABLE(); |
|
|
|
public: |
|
|
|
virtual void Spawn( void ); |
|
virtual void Precache(); |
|
|
|
virtual int Restore( IRestore &restore ); |
|
|
|
virtual const impactdamagetable_t &GetPhysicsImpactDamageTable( void ); |
|
|
|
int TakeHealth( float flHealth, int bitsDamageType ); |
|
void CauseDeath( const CTakeDamageInfo &info ); |
|
|
|
virtual bool FVisible ( CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); // true iff the parameter can be seen by me. |
|
virtual bool FVisible( const Vector &vecTarget, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ) { return BaseClass::FVisible( vecTarget, traceMask, ppBlocker ); } |
|
static void ResetVisibilityCache( CBaseCombatCharacter *pBCC = NULL ); |
|
|
|
#ifdef PORTAL |
|
virtual bool FVisibleThroughPortal( const CProp_Portal *pPortal, CBaseEntity *pEntity, int traceMask = MASK_BLOCKLOS, CBaseEntity **ppBlocker = NULL ); |
|
#endif |
|
|
|
virtual bool FInViewCone( CBaseEntity *pEntity ); |
|
virtual bool FInViewCone( const Vector &vecSpot ); |
|
|
|
#ifdef PORTAL |
|
virtual CProp_Portal* FInViewConeThroughPortal( CBaseEntity *pEntity ); |
|
virtual CProp_Portal* FInViewConeThroughPortal( const Vector &vecSpot ); |
|
#endif |
|
|
|
virtual bool FInAimCone( CBaseEntity *pEntity ); |
|
virtual bool FInAimCone( const Vector &vecSpot ); |
|
|
|
virtual bool ShouldShootMissTarget( CBaseCombatCharacter *pAttacker ); |
|
virtual CBaseEntity *FindMissTarget( void ); |
|
|
|
// Do not call HandleInteraction directly, use DispatchInteraction |
|
bool DispatchInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ) { return ( interactionType > 0 ) ? HandleInteraction( interactionType, data, sourceEnt ) : false; } |
|
virtual bool HandleInteraction( int interactionType, void *data, CBaseCombatCharacter* sourceEnt ); |
|
|
|
virtual QAngle BodyAngles(); |
|
virtual Vector BodyDirection2D( void ); |
|
virtual Vector BodyDirection3D( void ); |
|
virtual Vector HeadDirection2D( void ) { return BodyDirection2D( ); }; // No head motion so just return body dir |
|
virtual Vector HeadDirection3D( void ) { return BodyDirection2D( ); }; // No head motion so just return body dir |
|
virtual Vector EyeDirection2D( void ) { return HeadDirection2D( ); }; // No eye motion so just return head dir |
|
virtual Vector EyeDirection3D( void ) { return HeadDirection3D( ); }; // No eye motion so just return head dir |
|
|
|
virtual void SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways ); |
|
|
|
// ----------------------- |
|
// Fog |
|
// ----------------------- |
|
virtual bool IsHiddenByFog( const Vector &target ) const; ///< return true if given target cant be seen because of fog |
|
virtual bool IsHiddenByFog( CBaseEntity *target ) const; ///< return true if given target cant be seen because of fog |
|
virtual bool IsHiddenByFog( float range ) const; ///< return true if given distance is too far to see through the fog |
|
virtual float GetFogObscuredRatio( const Vector &target ) const;///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured |
|
virtual float GetFogObscuredRatio( CBaseEntity *target ) const; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured |
|
virtual float GetFogObscuredRatio( float range ) const; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured |
|
|
|
|
|
// ----------------------- |
|
// Vision |
|
// ----------------------- |
|
enum FieldOfViewCheckType { USE_FOV, DISREGARD_FOV }; |
|
|
|
// Visible starts with line of sight, and adds all the extra game checks like fog, smoke, camo... |
|
bool IsAbleToSee( const CBaseEntity *entity, FieldOfViewCheckType checkFOV ); |
|
bool IsAbleToSee( CBaseCombatCharacter *pBCC, FieldOfViewCheckType checkFOV ); |
|
|
|
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. |
|
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. |
|
|
|
virtual bool IsInFieldOfView( CBaseEntity *entity ) const; // Calls IsLookingTowards with the current field of view. |
|
virtual bool IsInFieldOfView( const Vector &pos ) const; |
|
|
|
enum LineOfSightCheckType |
|
{ |
|
IGNORE_NOTHING, |
|
IGNORE_ACTORS |
|
}; |
|
virtual bool IsLineOfSightClear( CBaseEntity *entity, LineOfSightCheckType checkType = IGNORE_NOTHING ) const;// strictly LOS check with no other considerations |
|
virtual bool IsLineOfSightClear( const Vector &pos, LineOfSightCheckType checkType = IGNORE_NOTHING, CBaseEntity *entityToIgnore = NULL ) const; |
|
|
|
// ----------------------- |
|
// Ammo |
|
// ----------------------- |
|
virtual int GiveAmmo( int iCount, int iAmmoIndex, bool bSuppressSound = false ); |
|
int GiveAmmo( int iCount, const char *szName, bool bSuppressSound = false ); |
|
virtual void RemoveAmmo( int iCount, int iAmmoIndex ); |
|
virtual void RemoveAmmo( int iCount, const char *szName ); |
|
void RemoveAllAmmo( ); |
|
virtual int GetAmmoCount( int iAmmoIndex ) const; |
|
int GetAmmoCount( char *szName ) const; |
|
|
|
virtual Activity NPC_TranslateActivity( Activity baseAct ); |
|
|
|
// ----------------------- |
|
// Weapons |
|
// ----------------------- |
|
CBaseCombatWeapon* Weapon_Create( const char *pWeaponName ); |
|
virtual Activity Weapon_TranslateActivity( Activity baseAct, bool *pRequired = NULL ); |
|
void Weapon_SetActivity( Activity newActivity, float duration ); |
|
virtual void Weapon_FrameUpdate( void ); |
|
virtual void Weapon_HandleAnimEvent( animevent_t *pEvent ); |
|
CBaseCombatWeapon* Weapon_OwnsThisType( const char *pszWeapon, int iSubType = 0 ) const; // True if already owns a weapon of this class |
|
virtual bool Weapon_CanUse( CBaseCombatWeapon *pWeapon ); // True is allowed to use this class of weapon |
|
virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon ); // Adds weapon to player |
|
virtual bool Weapon_EquipAmmoOnly( CBaseCombatWeapon *pWeapon ); // Adds weapon ammo to player, leaves weapon |
|
bool Weapon_Detach( CBaseCombatWeapon *pWeapon ); // Clear any pointers to the weapon. |
|
virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget = NULL, const Vector *pVelocity = NULL ); |
|
virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed) |
|
virtual Vector Weapon_ShootPosition( ); // gun position at current position/orientation |
|
bool Weapon_IsOnGround( CBaseCombatWeapon *pWeapon ); |
|
CBaseEntity* Weapon_FindUsable( const Vector &range ); // search for a usable weapon in this range |
|
virtual bool Weapon_CanSwitchTo(CBaseCombatWeapon *pWeapon); |
|
virtual bool Weapon_SlotOccupied( CBaseCombatWeapon *pWeapon ); |
|
virtual CBaseCombatWeapon *Weapon_GetSlot( int slot ) const; |
|
CBaseCombatWeapon *Weapon_GetWpnForAmmo( int iAmmoIndex ); |
|
|
|
|
|
// For weapon strip |
|
void Weapon_DropAll( bool bDisallowWeaponPickup = false ); |
|
|
|
virtual bool AddPlayerItem( CBaseCombatWeapon *pItem ) { return false; } |
|
virtual bool RemovePlayerItem( CBaseCombatWeapon *pItem ) { return false; } |
|
|
|
virtual bool CanBecomeServerRagdoll( void ) { return true; } |
|
|
|
// ----------------------- |
|
// Damage |
|
// ----------------------- |
|
// Don't override this for characters, override the per-life-state versions below |
|
virtual int OnTakeDamage( const CTakeDamageInfo &info ); |
|
|
|
// Override these to control how your character takes damage in different states |
|
virtual int OnTakeDamage_Alive( const CTakeDamageInfo &info ); |
|
virtual int OnTakeDamage_Dying( const CTakeDamageInfo &info ); |
|
virtual int OnTakeDamage_Dead( const CTakeDamageInfo &info ); |
|
|
|
virtual float GetAliveDuration( void ) const; // return time we have been alive (only valid when alive) |
|
|
|
virtual void OnFriendDamaged( CBaseCombatCharacter *pSquadmate, CBaseEntity *pAttacker ) {} |
|
virtual void NotifyFriendsOfDamage( CBaseEntity *pAttackerEntity ) {} |
|
virtual bool HasEverBeenInjured( int team = TEAM_ANY ) const; // return true if we have ever been injured by a member of the given team |
|
virtual float GetTimeSinceLastInjury( int team = TEAM_ANY ) const; // return time since we were hurt by a member of the given team |
|
|
|
|
|
virtual void OnPlayerKilledOther( CBaseEntity *pVictim, const CTakeDamageInfo &info ) {} |
|
|
|
// utility function to calc damage force |
|
Vector CalcDamageForceVector( const CTakeDamageInfo &info ); |
|
|
|
virtual int BloodColor(); |
|
virtual Activity GetDeathActivity( void ); |
|
|
|
virtual bool CorpseGib( const CTakeDamageInfo &info ); |
|
virtual void CorpseFade( void ); // Called instead of GibNPC() when gibs are disabled |
|
virtual bool HasHumanGibs( void ); |
|
virtual bool HasAlienGibs( void ); |
|
virtual bool ShouldGib( const CTakeDamageInfo &info ) { return false; } // Always ragdoll, unless specified by the leaf class |
|
|
|
float GetDamageAccumulator() { return m_flDamageAccumulator; } |
|
int GetDamageCount( void ) { return m_iDamageCount; } // # of times NPC has been damaged. used for tracking 1-shot kills. |
|
|
|
// Character killed (only fired once) |
|
virtual void Event_Killed( const CTakeDamageInfo &info ); |
|
|
|
// Killed a character |
|
void InputKilledNPC( inputdata_t &inputdata ); |
|
virtual void OnKilledNPC( CBaseCombatCharacter *pKilled ) {}; |
|
|
|
// Exactly one of these happens immediately after killed (gibbed may happen later when the corpse gibs) |
|
// Character gibbed or faded out (violence controls) (only fired once) |
|
// returns true if gibs were spawned |
|
virtual bool Event_Gibbed( const CTakeDamageInfo &info ); |
|
// Character entered the dying state without being gibbed (only fired once) |
|
virtual void Event_Dying( const CTakeDamageInfo &info ); |
|
virtual void Event_Dying(); |
|
// character died and should become a ragdoll now |
|
// return true if converted to a ragdoll, false to use AI death |
|
virtual bool BecomeRagdoll( const CTakeDamageInfo &info, const Vector &forceVector ); |
|
virtual void FixupBurningServerRagdoll( CBaseEntity *pRagdoll ); |
|
|
|
virtual bool BecomeRagdollBoogie( CBaseEntity *pKiller, const Vector &forceVector, float duration, int flags ); |
|
|
|
CBaseEntity *FindHealthItem( const Vector &vecPosition, const Vector &range ); |
|
|
|
|
|
virtual CBaseEntity *CheckTraceHullAttack( float flDist, const Vector &mins, const Vector &maxs, int iDamage, int iDmgType, float forceScale = 1.0f, bool bDamageAnyNPC = false ); |
|
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 ); |
|
|
|
virtual CBaseCombatCharacter *MyCombatCharacterPointer( void ) { return this; } |
|
|
|
// VPHYSICS |
|
virtual void VPhysicsShadowCollision( int index, gamevcollisionevent_t *pEvent ); |
|
virtual void VPhysicsUpdate( IPhysicsObject *pPhysics ); |
|
float CalculatePhysicsStressDamage( vphysics_objectstress_t *pStressOut, IPhysicsObject *pPhysics ); |
|
void ApplyStressDamage( IPhysicsObject *pPhysics, bool bRequireLargeObject ); |
|
|
|
virtual void PushawayTouch( CBaseEntity *pOther ) {} |
|
|
|
void SetImpactEnergyScale( float fScale ) { m_impactEnergyScale = fScale; } |
|
|
|
virtual void UpdateOnRemove( void ); |
|
|
|
virtual Disposition_t IRelationType( CBaseEntity *pTarget ); |
|
virtual int IRelationPriority( CBaseEntity *pTarget ); |
|
|
|
virtual void SetLightingOriginRelative( CBaseEntity *pLightingOrigin ); |
|
|
|
protected: |
|
Relationship_t *FindEntityRelationship( CBaseEntity *pTarget ); |
|
|
|
public: |
|
|
|
// Vehicle queries |
|
virtual bool IsInAVehicle( void ) const { return false; } |
|
virtual IServerVehicle *GetVehicle( void ) { return NULL; } |
|
virtual CBaseEntity *GetVehicleEntity( void ) { return NULL; } |
|
virtual bool ExitVehicle( void ) { return false; } |
|
|
|
// Blood color (see BLOOD_COLOR_* macros in baseentity.h) |
|
void SetBloodColor( int nBloodColor ); |
|
|
|
// Weapons.. |
|
CBaseCombatWeapon* GetActiveWeapon() const; |
|
int WeaponCount() const; |
|
CBaseCombatWeapon* GetWeapon( int i ) const; |
|
bool RemoveWeapon( CBaseCombatWeapon *pWeapon ); |
|
virtual void RemoveAllWeapons(); |
|
WeaponProficiency_t GetCurrentWeaponProficiency() { return m_CurrentWeaponProficiency; } |
|
void SetCurrentWeaponProficiency( WeaponProficiency_t iProficiency ) { m_CurrentWeaponProficiency = iProficiency; } |
|
virtual WeaponProficiency_t CalcWeaponProficiency( CBaseCombatWeapon *pWeapon ); |
|
virtual Vector GetAttackSpread( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget = NULL ); |
|
virtual float GetSpreadBias( CBaseCombatWeapon *pWeapon, CBaseEntity *pTarget ); |
|
virtual void DoMuzzleFlash(); |
|
|
|
// Interactions |
|
static void InitInteractionSystem(); |
|
|
|
// Relationships |
|
static void AllocateDefaultRelationships( ); |
|
static void SetDefaultRelationship( Class_T nClass, Class_T nClassTarget, Disposition_t nDisposition, int nPriority ); |
|
Disposition_t GetDefaultRelationshipDisposition( Class_T nClassTarget ); |
|
virtual void AddEntityRelationship( CBaseEntity *pEntity, Disposition_t nDisposition, int nPriority ); |
|
virtual bool RemoveEntityRelationship( CBaseEntity *pEntity ); |
|
virtual void AddClassRelationship( Class_T nClass, Disposition_t nDisposition, int nPriority ); |
|
|
|
virtual void ChangeTeam( int iTeamNum ); |
|
|
|
// Nav hull type |
|
Hull_t GetHullType() const { return m_eHull; } |
|
void SetHullType( Hull_t hullType ) { m_eHull = hullType; } |
|
|
|
// FIXME: The following 3 methods are backdoor hack methods |
|
|
|
// This is a sort of hack back-door only used by physgun! |
|
void SetAmmoCount( int iCount, int iAmmoIndex ); |
|
|
|
// This is a hack to blat out the current active weapon... |
|
// Used by weapon_slam + game_ui |
|
void SetActiveWeapon( CBaseCombatWeapon *pNewWeapon ); |
|
void ClearActiveWeapon() { SetActiveWeapon( NULL ); } |
|
virtual void OnChangeActiveWeapon( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) {} |
|
|
|
// I can't use my current weapon anymore. Switch me to the next best weapon. |
|
bool SwitchToNextBestWeapon(CBaseCombatWeapon *pCurrent); |
|
|
|
// This is a hack to copy the relationship strings used by monstermaker |
|
void SetRelationshipString( string_t theString ) { m_RelationshipString = theString; } |
|
|
|
float GetNextAttack() const { return m_flNextAttack; } |
|
void SetNextAttack( float flWait ) { m_flNextAttack = flWait; } |
|
|
|
bool m_bForceServerRagdoll; |
|
|
|
// Pickup prevention |
|
bool IsAllowedToPickupWeapons( void ) { return !m_bPreventWeaponPickup; } |
|
void SetPreventWeaponPickup( bool bPrevent ) { m_bPreventWeaponPickup = bPrevent; } |
|
bool m_bPreventWeaponPickup; |
|
|
|
virtual CNavArea *GetLastKnownArea( void ) const |
|
{ |
|
#ifdef NEXT_BOT |
|
return m_lastNavArea; |
|
#else |
|
return NULL; |
|
#endif |
|
} // return the last nav area the player occupied - NULL if unknown |
|
|
|
virtual void ClearLastKnownArea( void ); |
|
virtual void UpdateLastKnownArea( void ); // invoke this to update our last known nav area (since there is no think method chained to CBaseCombatCharacter) |
|
virtual void OnNavAreaChanged( CNavArea *enteredArea, CNavArea *leftArea ) { } // invoked (by UpdateLastKnownArea) when we enter a new nav area (or it is reset to NULL) |
|
virtual bool IsAreaTraversable( const CNavArea *area ) const; // return true if we can use the given area |
|
virtual void OnNavAreaRemoved( CNavArea *removedArea ); |
|
|
|
// ----------------------- |
|
// Notification from INextBots. |
|
// ----------------------- |
|
virtual void OnPursuedBy( INextBot * RESTRICT pPursuer ){} // called every frame while pursued by a bot in DirectChase. |
|
|
|
#ifdef GLOWS_ENABLE |
|
// Glows |
|
void AddGlowEffect( void ); |
|
void RemoveGlowEffect( void ); |
|
bool IsGlowEffectActive( void ); |
|
#endif // GLOWS_ENABLE |
|
|
|
#ifdef INVASION_DLL |
|
public: |
|
|
|
|
|
// TF2 Powerups |
|
virtual bool CanBePoweredUp( void ); |
|
bool HasPowerup( int iPowerup ); |
|
virtual bool CanPowerupNow( int iPowerup ); // Return true if I can be powered by this powerup right now |
|
virtual bool CanPowerupEver( int iPowerup ); // Return true if I ever accept this powerup type |
|
|
|
void SetPowerup( int iPowerup, bool bState, float flTime = 0, float flAmount = 0, CBaseEntity *pAttacker = NULL, CDamageModifier *pDamageModifier = NULL ); |
|
virtual bool AttemptToPowerup( int iPowerup, float flTime, float flAmount = 0, CBaseEntity *pAttacker = NULL, CDamageModifier *pDamageModifier = NULL ); |
|
virtual float PowerupDuration( int iPowerup, float flTime ); |
|
virtual void PowerupStart( int iPowerup, float flAmount = 0, CBaseEntity *pAttacker = NULL, CDamageModifier *pDamageModifier = NULL ); |
|
virtual void PowerupEnd( int iPowerup ); |
|
|
|
void PowerupThink( void ); |
|
virtual void PowerupThink( int iPowerup ); |
|
|
|
public: |
|
|
|
CNetworkVar( int, m_iPowerups ); |
|
float m_flPowerupAttemptTimes[ MAX_POWERUPS ]; |
|
float m_flPowerupEndTimes[ MAX_POWERUPS ]; |
|
float m_flFractionalBoost; // POWERUP_BOOST health fraction - specific powerup data |
|
|
|
#endif |
|
|
|
public: |
|
// returns the last body region that took damage |
|
int LastHitGroup() const { return m_LastHitGroup; } |
|
protected: |
|
void SetLastHitGroup( int nHitGroup ) { m_LastHitGroup = nHitGroup; } |
|
|
|
public: |
|
CNetworkVar( float, m_flNextAttack ); // cannot attack again until this time |
|
|
|
#ifdef GLOWS_ENABLE |
|
protected: |
|
CNetworkVar( bool, m_bGlowEnabled ); |
|
#endif // GLOWS_ENABLE |
|
|
|
private: |
|
Hull_t m_eHull; |
|
|
|
void UpdateGlowEffect( void ); |
|
void DestroyGlowEffect( void ); |
|
|
|
protected: |
|
int m_bloodColor; // color of blood particless |
|
|
|
// ------------------- |
|
// combat ability data |
|
// ------------------- |
|
float m_flFieldOfView; // cosine of field of view for this character |
|
Vector m_HackedGunPos; // HACK until we can query end of gun |
|
string_t m_RelationshipString; // Used to load up relationship keyvalues |
|
float m_impactEnergyScale;// scale the amount of energy used to calculate damage this ent takes due to physics |
|
|
|
public: |
|
static int GetInteractionID(); // Returns the next interaction # |
|
|
|
protected: |
|
// Visibility-related stuff |
|
bool ComputeLOS( const Vector &vecEyePosition, const Vector &vecTarget ) const; |
|
private: |
|
// For weapon strip |
|
void ThrowDirForWeaponStrip( CBaseCombatWeapon *pWeapon, const Vector &vecForward, Vector *pVecThrowDir ); |
|
void DropWeaponForWeaponStrip( CBaseCombatWeapon *pWeapon, const Vector &vecForward, const QAngle &vecAngles, float flDiameter ); |
|
|
|
friend class CScriptedTarget; // needs to access GetInteractionID() |
|
|
|
static int m_lastInteraction; // Last registered interaction # |
|
static Relationship_t** m_DefaultRelationship; |
|
|
|
// attack/damage |
|
int m_LastHitGroup; // the last body region that took damage |
|
float m_flDamageAccumulator; // so very small amounts of damage do not get lost. |
|
int m_iDamageCount; // # of times NPC has been damaged. used for tracking 1-shot kills. |
|
|
|
// Weapon proficiency gets calculated each time an NPC changes his weapon, and then |
|
// cached off as the CurrentWeaponProficiency. |
|
WeaponProficiency_t m_CurrentWeaponProficiency; |
|
|
|
// --------------- |
|
// Relationships |
|
// --------------- |
|
CUtlVector<Relationship_t> m_Relationship; // Array of relationships |
|
|
|
protected: |
|
// shared ammo slots |
|
CNetworkArrayForDerived( int, m_iAmmo, MAX_AMMO_SLOTS ); |
|
|
|
// Usable character items |
|
CNetworkArray( CBaseCombatWeaponHandle, m_hMyWeapons, MAX_WEAPONS ); |
|
|
|
CNetworkHandle( CBaseCombatWeapon, m_hActiveWeapon ); |
|
|
|
friend class CCleanupDefaultRelationShips; |
|
|
|
IntervalTimer m_aliveTimer; |
|
|
|
unsigned int m_hasBeenInjured; // bitfield corresponding to team ID that did the injury |
|
|
|
// we do this because MAX_TEAMS is 32, which is wasteful for most games |
|
enum { MAX_DAMAGE_TEAMS = 4 }; |
|
struct DamageHistory |
|
{ |
|
int team; // which team hurt us (TEAM_INVALID means slot unused) |
|
IntervalTimer interval; // how long has it been |
|
}; |
|
DamageHistory m_damageHistory[ MAX_DAMAGE_TEAMS ]; |
|
|
|
// last known navigation area of player - NULL if unknown |
|
CNavArea *m_lastNavArea; |
|
CAI_MoveMonitor m_NavAreaUpdateMonitor; |
|
int m_registeredNavTeam; // ugly, but needed to clean up player team counts in nav mesh |
|
}; |
|
|
|
|
|
inline float CBaseCombatCharacter::GetAliveDuration( void ) const |
|
{ |
|
return m_aliveTimer.GetElapsedTime(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
inline int CBaseCombatCharacter::WeaponCount() const |
|
{ |
|
return MAX_WEAPONS; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : i - |
|
//----------------------------------------------------------------------------- |
|
inline CBaseCombatWeapon *CBaseCombatCharacter::GetWeapon( int i ) const |
|
{ |
|
Assert( (i >= 0) && (i < MAX_WEAPONS) ); |
|
return m_hMyWeapons[i].Get(); |
|
} |
|
|
|
#ifdef INVASION_DLL |
|
// Powerup Inlines |
|
inline bool CBaseCombatCharacter::CanBePoweredUp( void ) { return true; } |
|
inline float CBaseCombatCharacter::PowerupDuration( int iPowerup, float flTime ) { return flTime; } |
|
inline void CBaseCombatCharacter::PowerupEnd( int iPowerup ) { return; } |
|
inline void CBaseCombatCharacter::PowerupThink( int iPowerup ) { return; } |
|
#endif |
|
|
|
EXTERN_SEND_TABLE(DT_BaseCombatCharacter); |
|
|
|
void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
class CTraceFilterMelee : public CTraceFilterEntitiesOnly |
|
{ |
|
public: |
|
// It does have a base, but we'll never network anything below here.. |
|
DECLARE_CLASS_NOBASE( CTraceFilterMelee ); |
|
|
|
CTraceFilterMelee( const IHandleEntity *passentity, int collisionGroup, CTakeDamageInfo *dmgInfo, float flForceScale, bool bDamageAnyNPC ) |
|
: m_pPassEnt(passentity), m_collisionGroup(collisionGroup), m_dmgInfo(dmgInfo), m_pHit(NULL), m_flForceScale(flForceScale), m_bDamageAnyNPC(bDamageAnyNPC) |
|
{ |
|
} |
|
|
|
virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ); |
|
|
|
public: |
|
const IHandleEntity *m_pPassEnt; |
|
int m_collisionGroup; |
|
CTakeDamageInfo *m_dmgInfo; |
|
CBaseEntity *m_pHit; |
|
float m_flForceScale; |
|
bool m_bDamageAnyNPC; |
|
}; |
|
|
|
#endif // BASECOMBATCHARACTER_H
|
|
|