CBaseCombatCharacter: Difference between revisions
Gameplayer (talk | contribs) mNo edit summary |
No edit summary |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{stub}} | {{stub}} | ||
{{CD|CBaseCombatCharacter|base=CBaseFlex|file1=[https://github.com/ValveSoftware/source-sdk-2013/blob/master | {{CD|CBaseCombatCharacter|base=CBaseFlex|file1=[https://github.com/ValveSoftware/source-sdk-2013/blob/master/src/game/server/basecombatcharacter.cpp basecombatcharacter.cpp]}} | ||
<code>CBaseCombatCharacter</code> is the class base used for characters, NPCs and players alike, without AI. | <code>CBaseCombatCharacter</code> is the class base used for characters, NPCs and players alike, without AI. | ||
==Keyvalues== | <!--==Keyvalues== | ||
{{KV BaseCombatCharacter}} | {{KV BaseCombatCharacter}} | ||
==Inputs== | ==Inputs== | ||
{{I BaseCombatCharacter}} | {{I BaseCombatCharacter}}--> | ||
==Keyfields== | |||
{{DEFINE_KEYFIELD|m_RelationshipString|FIELD_STRING|Relationship|<[[string]]|[[targetname]] or [[classname]]> <[[string]]|disposition> <[[int]]|rank> | |||
:Changes whether this entity likes or dislikes certain other things. Used like the {{ent|ai_relationship}} entity, with this entity as the subject. | |||
:Values for <code>disposition</code> are: | |||
:*<code>D_HT</code>: Hate | |||
:*<code>D_FR</code>: Fear | |||
:*<code>D_LI</code>: Like | |||
:*<code>D_NU</code>: Neutral}} | |||
{{DEFINE_INPUT|m_impactEnergyScale|FIELD_FLOAT|physdamagescale|Scales damage energy when this character is hit by a physics object. With a value of 0 the NPC will take no damage from physics.}} | |||
==Inputs== | |||
{{DEFINE_INPUTFUNC|FIELD_VOID|KilledNPC|InputKilledNPC|Tells the entity it killed something. Despite the name, this can include a player. This input will be automatically sent by the victim when they die.}} | |||
==Fields== | |||
{{DEFINE_FIELD|m_flNextAttack|FIELD_TIME}} | |||
{{DEFINE_FIELD|m_eHull|FIELD_INTEGER}} | |||
{{DEFINE_FIELD|m_bloodColor|FIELD_INTEGER}} | |||
{{DEFINE_FIELD|m_iDamageCount|FIELD_INTEGER}} | |||
{{DEFINE_FIELD|m_flFieldOfView|FIELD_FLOAT}} | |||
{{DEFINE_FIELD|m_HackedGunPos|FIELD_VECTOR}} | |||
{{DEFINE_FIELD|m_LastHitGroup|FIELD_INTEGER}} | |||
{{DEFINE_FIELD|m_flDamageAccumulator|FIELD_FLOAT}} | |||
{{DEFINE_FIELD|m_CurrentWeaponProficiency|FIELD_INTEGER}} | |||
{{DEFINE_ARRAY|m_iAmmo|FIELD_INTEGER|}} | |||
{{DEFINE_ARRAY|m_hMyWeapons|FIELD_EHANDLE|}} | |||
{{DEFINE_FIELD|m_hActiveWeapon|FIELD_EHANDLE}} | |||
{{DEFINE_FIELD|m_bForceServerRagdoll|FIELD_BOOLEAN}} | |||
{{DEFINE_FIELD|m_bPreventWeaponPickup|FIELD_BOOLEAN}} | |||
{{DEFINE_FIELD|m_iPowerups|FIELD_INTEGER|game={{tf2|in}}}} | |||
{{DEFINE_FIELD|m_flFractionalBoost|FIELD_FLOAT|game={{tf2|in}}}} | |||
{{DEFINE_ARRAY|m_flPowerupAttemptTimes|FIELD_TIME|MAX_POWERUPS|game={{tf2|in}}}} | |||
{{DEFINE_ARRAY|m_flPowerupEndTimes|FIELD_TIME|MAX_POWERUPS|game={{tf2|in}}}} | |||
<!-- classdefs --> | |||
{{Class def section}} |
Latest revision as of 09:37, 18 July 2025
![]() |
---|
CBaseCombatCharacter |
![]() |
CBaseCombatCharacter
is the class base used for characters, NPCs and players alike, without AI.
Keyfields
m_RelationshipString <FIELD_STRING> (Relationship)
- <string|targetname or classname> <string|disposition> <int|rank>
- Changes whether this entity likes or dislikes certain other things. Used like the ai_relationship entity, with this entity as the subject.
- Values for
disposition
are:D_HT
: HateD_FR
: FearD_LI
: LikeD_NU
: Neutral
m_impactEnergyScale <FIELD_FLOAT> (physdamagescale)
- Scales damage energy when this character is hit by a physics object. With a value of 0 the NPC will take no damage from physics.
Inputs
KilledNPC <FIELD_VOID> linked function: InputKilledNPC
- Tells the entity it killed something. Despite the name, this can include a player. This input will be automatically sent by the victim when they die.
Fields
m_flNextAttack <FIELD_TIME>
m_eHull <FIELD_INTEGER>
m_bloodColor <FIELD_INTEGER>
m_iDamageCount <FIELD_INTEGER>
m_flFieldOfView <FIELD_FLOAT>
m_HackedGunPos <FIELD_VECTOR>
m_LastHitGroup <FIELD_INTEGER>
m_flDamageAccumulator <FIELD_FLOAT>
m_CurrentWeaponProficiency <FIELD_INTEGER>
m_iAmmo[] <FIELD_INTEGER>
m_hMyWeapons[] <FIELD_EHANDLE>
m_hActiveWeapon <FIELD_EHANDLE>
m_bForceServerRagdoll <FIELD_BOOLEAN>
m_bPreventWeaponPickup <FIELD_BOOLEAN>
m_iPowerups (in )<FIELD_INTEGER>
m_flFractionalBoost (in )<FIELD_FLOAT>
m_flPowerupAttemptTimes[MAX_POWERUPS] (in )<FIELD_TIME>
m_flPowerupEndTimes[MAX_POWERUPS] (in )<FIELD_TIME>
C++ definitions from
Source 2013 Multiplayer [edit]
Serverside
basecombatcharacter.h
//-----------------------------------------------------------------------------
// 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();
DECLARE_ENT_SCRIPTDESC();
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 ) OVERRIDE;
// 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 { return m_lastNavArea; } // return the last nav area the player occupied - NULL if unknown
HSCRIPT ScriptGetLastKnownArea( void ) const;
virtual bool IsAreaTraversable( const CNavArea *area ) const; // return true if we can use the given area
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 void OnNavAreaRemoved( CNavArea *removedArea );
// -----------------------
// Notification from INextBots.
// -----------------------
virtual void OnPursuedBy( INextBot * RESTRICT pPursuer ){} // called every frame while pursued by a bot in DirectChase.
#ifdef TF_DLL
virtual HalloweenBossType GetBossType() const { return HALLOWEEN_BOSS_INVALID; }
#endif // TF_DLL
#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
};
basecombatcharacter.cpp
BEGIN_DATADESC( CBaseCombatCharacter )
#ifdef INVASION_DLL
DEFINE_FIELD( m_iPowerups, FIELD_INTEGER ),
DEFINE_ARRAY( m_flPowerupAttemptTimes, FIELD_TIME, MAX_POWERUPS ),
DEFINE_ARRAY( m_flPowerupEndTimes, FIELD_TIME, MAX_POWERUPS ),
DEFINE_FIELD( m_flFractionalBoost, FIELD_FLOAT ),
#endif
DEFINE_FIELD( m_flNextAttack, FIELD_TIME ),
DEFINE_FIELD( m_eHull, FIELD_INTEGER ),
DEFINE_FIELD( m_bloodColor, FIELD_INTEGER ),
DEFINE_FIELD( m_iDamageCount, FIELD_INTEGER ),
DEFINE_FIELD( m_flFieldOfView, FIELD_FLOAT ),
DEFINE_FIELD( m_HackedGunPos, FIELD_VECTOR ),
DEFINE_KEYFIELD( m_RelationshipString, FIELD_STRING, "Relationship" ),
DEFINE_FIELD( m_LastHitGroup, FIELD_INTEGER ),
DEFINE_FIELD( m_flDamageAccumulator, FIELD_FLOAT ),
DEFINE_INPUT( m_impactEnergyScale, FIELD_FLOAT, "physdamagescale" ),
DEFINE_FIELD( m_CurrentWeaponProficiency, FIELD_INTEGER),
DEFINE_UTLVECTOR( m_Relationship, FIELD_EMBEDDED),
DEFINE_AUTO_ARRAY( m_iAmmo, FIELD_INTEGER ),
DEFINE_AUTO_ARRAY( m_hMyWeapons, FIELD_EHANDLE ),
DEFINE_FIELD( m_hActiveWeapon, FIELD_EHANDLE ),
DEFINE_FIELD( m_bForceServerRagdoll, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bPreventWeaponPickup, FIELD_BOOLEAN ),
DEFINE_INPUTFUNC( FIELD_VOID, "KilledNPC", InputKilledNPC ),
END_DATADESC()