This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
nekohook/modules/source2013/sdk/game/server/basecombatcharacter.h
2020-08-04 13:13:01 -04:00

750 lines
30 KiB
C++

//========= 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 "ai_hull.h"
#include "ai_utils.h"
#include "baseentity.h"
#include "baseflex.h"
#include "cbase.h"
#include "damagemodifier.h"
#include "physics_impact_damage.h"
#include "utllinkedlist.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 {
return m_lastNavArea;
} // return the last nav area the player occupied - NULL if unknown
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 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