//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef TAKEDAMAGEINFO_H #define TAKEDAMAGEINFO_H #ifdef _WIN32 #pragma once #endif #include "networkvar.h" // todo: change this when DECLARE_CLASS is moved into a better location. // Used to initialize m_flBaseDamage to something that we know pretty much for sure // hasn't been modified by a user. #define BASEDAMAGE_NOT_SPECIFIED FLT_MAX class CBaseEntity; class CTakeDamageInfo { public: enum ECritType { CRIT_NONE = 0, CRIT_MINI, CRIT_FULL, }; DECLARE_CLASS_NOBASE( CTakeDamageInfo ); CTakeDamageInfo(); CTakeDamageInfo( CBaseEntity *pInflictor, CBaseEntity *pAttacker, float flDamage, int bitsDamageType, int iKillType = 0 ); CTakeDamageInfo( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, float flDamage, int bitsDamageType, int iKillType = 0 ); CTakeDamageInfo( CBaseEntity *pInflictor, CBaseEntity *pAttacker, const Vector &damageForce, const Vector &damagePosition, float flDamage, int bitsDamageType, int iKillType = 0, Vector *reportedPosition = NULL ); CTakeDamageInfo( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, float flDamage, int bitsDamageType, int iKillType = 0, Vector *reportedPosition = NULL ); // Inflictor is the weapon or rocket (or player) that is dealing the damage. CBaseEntity* GetInflictor() const; void SetInflictor( CBaseEntity *pInflictor ); // Weapon is the weapon that did the attack. // For hitscan weapons, it'll be the same as the inflictor. For projectile weapons, the projectile // is the inflictor, and this contains the weapon that created the projectile. CBaseEntity* GetWeapon() const; void SetWeapon( CBaseEntity *pWeapon ); // Attacker is the character who originated the attack (like a player or an AI). CBaseEntity* GetAttacker() const; void SetAttacker( CBaseEntity *pAttacker ); float GetDamage() const; void SetDamage( float flDamage ); float GetMaxDamage() const; void SetMaxDamage( float flMaxDamage ); void ScaleDamage( float flScaleAmount ); void AddDamage( float flAddAmount ); void SubtractDamage( float flSubtractAmount ); float GetDamageBonus() const; CBaseEntity *GetDamageBonusProvider() const; void SetDamageBonus( float flBonus, CBaseEntity *pProvider = NULL ); float GetBaseDamage() const; bool BaseDamageIsValid() const; Vector GetDamageForce() const; void SetDamageForce( const Vector &damageForce ); void ScaleDamageForce( float flScaleAmount ); float GetDamageForForceCalc() const; void SetDamageForForceCalc( const float flScaleAmount ); Vector GetDamagePosition() const; void SetDamagePosition( const Vector &damagePosition ); Vector GetReportedPosition() const; void SetReportedPosition( const Vector &reportedPosition ); int GetDamageType() const; void SetDamageType( int bitsDamageType ); void AddDamageType( int bitsDamageType ); int GetDamageCustom( void ) const; void SetDamageCustom( int iDamageCustom ); int GetDamageStats( void ) const; void SetDamageStats( int iDamageStats ); void SetForceFriendlyFire( bool bValue ) { m_bForceFriendlyFire = bValue; } bool IsForceFriendlyFire( void ) const { return m_bForceFriendlyFire; } int GetAmmoType() const; void SetAmmoType( int iAmmoType ); const char * GetAmmoName() const; int GetPlayerPenetrationCount() const { return m_iPlayerPenetrationCount; } void SetPlayerPenetrationCount( int iPlayerPenetrationCount ) { m_iPlayerPenetrationCount = iPlayerPenetrationCount; } int GetDamagedOtherPlayers() const { return m_iDamagedOtherPlayers; } void SetDamagedOtherPlayers( int iVal ) { m_iDamagedOtherPlayers = iVal; } void Set( CBaseEntity *pInflictor, CBaseEntity *pAttacker, float flDamage, int bitsDamageType, int iKillType = 0 ); void Set( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, float flDamage, int bitsDamageType, int iKillType = 0 ); void Set( CBaseEntity *pInflictor, CBaseEntity *pAttacker, const Vector &damageForce, const Vector &damagePosition, float flDamage, int bitsDamageType, int iKillType = 0, Vector *reportedPosition = NULL ); void Set( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, float flDamage, int bitsDamageType, int iKillType = 0, Vector *reportedPosition = NULL ); void AdjustPlayerDamageInflictedForSkillLevel(); void AdjustPlayerDamageTakenForSkillLevel(); // Given a damage type (composed of the #defines above), fill out a string with the appropriate text. // For designer debug output. static void DebugGetDamageTypeString(unsigned int DamageType, char *outbuf, int outbuflength ); void SetCritType( ECritType eType ); ECritType GetCritType() const { return m_eCritType; } //private: void CopyDamageToBaseDamage(); protected: void Init( CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, const Vector &reportedPosition, float flDamage, int bitsDamageType, int iKillType ); Vector m_vecDamageForce; Vector m_vecDamagePosition; Vector m_vecReportedPosition; // Position players are told damage is coming from EHANDLE m_hInflictor; EHANDLE m_hAttacker; EHANDLE m_hWeapon; float m_flDamage; float m_flMaxDamage; float m_flBaseDamage; // The damage amount before skill leve adjustments are made. Used to get uniform damage forces. int m_bitsDamageType; int m_iDamageCustom; int m_iDamageStats; int m_iAmmoType; // AmmoType of the weapon used to cause this damage, if any int m_iDamagedOtherPlayers; int m_iPlayerPenetrationCount; float m_flDamageBonus; // Anything that increases damage (crit) - store the delta EHANDLE m_hDamageBonusProvider; // Who gave us the ability to do extra damage? bool m_bForceFriendlyFire; // Ideally this would be a dmg type, but we can't add more float m_flDamageForForce; ECritType m_eCritType; DECLARE_SIMPLE_DATADESC(); }; //----------------------------------------------------------------------------- // Purpose: Multi damage. Used to collect multiple damages in the same frame (i.e. shotgun pellets) //----------------------------------------------------------------------------- class CMultiDamage : public CTakeDamageInfo { DECLARE_CLASS( CMultiDamage, CTakeDamageInfo ); public: CMultiDamage(); bool IsClear( void ) { return (m_hTarget == NULL); } CBaseEntity *GetTarget() const; void SetTarget( CBaseEntity *pTarget ); void Init( CBaseEntity *pTarget, CBaseEntity *pInflictor, CBaseEntity *pAttacker, CBaseEntity *pWeapon, const Vector &damageForce, const Vector &damagePosition, const Vector &reportedPosition, float flDamage, int bitsDamageType, int iKillType ); protected: EHANDLE m_hTarget; DECLARE_SIMPLE_DATADESC(); }; extern CMultiDamage g_MultiDamage; // Multidamage accessors void ClearMultiDamage( void ); void ApplyMultiDamage( void ); void AddMultiDamage( const CTakeDamageInfo &info, CBaseEntity *pEntity ); //----------------------------------------------------------------------------- // Purpose: Utility functions for physics damage force calculation //----------------------------------------------------------------------------- float ImpulseScale( float flTargetMass, float flDesiredSpeed ); void CalculateExplosiveDamageForce( CTakeDamageInfo *info, const Vector &vecDir, const Vector &vecForceOrigin, float flScale = 1.0 ); void CalculateBulletDamageForce( CTakeDamageInfo *info, int iBulletType, const Vector &vecBulletDir, const Vector &vecForceOrigin, float flScale = 1.0 ); void CalculateMeleeDamageForce( CTakeDamageInfo *info, const Vector &vecMeleeDir, const Vector &vecForceOrigin, float flScale = 1.0 ); void GuessDamageForce( CTakeDamageInfo *info, const Vector &vecForceDir, const Vector &vecForceOrigin, float flScale = 1.0 ); // -------------------------------------------------------------------------------------------------- // // Inlines. // -------------------------------------------------------------------------------------------------- // inline CBaseEntity* CTakeDamageInfo::GetInflictor() const { return m_hInflictor; } inline void CTakeDamageInfo::SetInflictor( CBaseEntity *pInflictor ) { m_hInflictor = pInflictor; } inline CBaseEntity* CTakeDamageInfo::GetAttacker() const { return m_hAttacker; } inline void CTakeDamageInfo::SetAttacker( CBaseEntity *pAttacker ) { m_hAttacker = pAttacker; } inline CBaseEntity* CTakeDamageInfo::GetWeapon() const { return m_hWeapon; } inline void CTakeDamageInfo::SetWeapon( CBaseEntity *pWeapon ) { m_hWeapon = pWeapon; } inline float CTakeDamageInfo::GetDamage() const { return m_flDamage; } inline void CTakeDamageInfo::SetDamage( float flDamage ) { m_flDamage = flDamage; } inline float CTakeDamageInfo::GetMaxDamage() const { return m_flMaxDamage; } inline void CTakeDamageInfo::SetMaxDamage( float flMaxDamage ) { m_flMaxDamage = flMaxDamage; } inline void CTakeDamageInfo::ScaleDamage( float flScaleAmount ) { m_flDamage *= flScaleAmount; } inline void CTakeDamageInfo::AddDamage( float flAddAmount ) { m_flDamage += flAddAmount; } inline void CTakeDamageInfo::SubtractDamage( float flSubtractAmount ) { m_flDamage -= flSubtractAmount; } inline float CTakeDamageInfo::GetDamageBonus() const { return m_flDamageBonus; } inline CBaseEntity *CTakeDamageInfo::GetDamageBonusProvider() const { return m_hDamageBonusProvider; } inline void CTakeDamageInfo::SetDamageBonus( float flBonus, CBaseEntity *pProvider /*= NULL*/ ) { m_flDamageBonus = flBonus; m_hDamageBonusProvider = pProvider; } inline float CTakeDamageInfo::GetBaseDamage() const { if( BaseDamageIsValid() ) return m_flBaseDamage; // No one ever specified a base damage, so just return damage. return m_flDamage; } inline bool CTakeDamageInfo::BaseDamageIsValid() const { return (m_flBaseDamage != BASEDAMAGE_NOT_SPECIFIED); } inline Vector CTakeDamageInfo::GetDamageForce() const { return m_vecDamageForce; } inline void CTakeDamageInfo::SetDamageForce( const Vector &damageForce ) { m_vecDamageForce = damageForce; } inline void CTakeDamageInfo::ScaleDamageForce( float flScaleAmount ) { m_vecDamageForce *= flScaleAmount; } inline float CTakeDamageInfo::GetDamageForForceCalc() const { return m_flDamageForForce; } inline void CTakeDamageInfo::SetDamageForForceCalc( float flDamage ) { m_flDamageForForce = flDamage; } inline Vector CTakeDamageInfo::GetDamagePosition() const { return m_vecDamagePosition; } inline void CTakeDamageInfo::SetDamagePosition( const Vector &damagePosition ) { m_vecDamagePosition = damagePosition; } inline Vector CTakeDamageInfo::GetReportedPosition() const { return m_vecReportedPosition; } inline void CTakeDamageInfo::SetReportedPosition( const Vector &reportedPosition ) { m_vecReportedPosition = reportedPosition; } inline void CTakeDamageInfo::SetDamageType( int bitsDamageType ) { m_bitsDamageType = bitsDamageType; } inline int CTakeDamageInfo::GetDamageType() const { return m_bitsDamageType; } inline void CTakeDamageInfo::AddDamageType( int bitsDamageType ) { m_bitsDamageType |= bitsDamageType; } inline int CTakeDamageInfo::GetDamageCustom() const { return m_iDamageCustom; } inline void CTakeDamageInfo::SetDamageCustom( int iDamageCustom ) { m_iDamageCustom = iDamageCustom; } inline int CTakeDamageInfo::GetDamageStats() const { return m_iDamageCustom; } inline void CTakeDamageInfo::SetDamageStats( int iDamageCustom ) { m_iDamageCustom = iDamageCustom; } inline int CTakeDamageInfo::GetAmmoType() const { return m_iAmmoType; } inline void CTakeDamageInfo::SetAmmoType( int iAmmoType ) { m_iAmmoType = iAmmoType; } inline void CTakeDamageInfo::CopyDamageToBaseDamage() { m_flBaseDamage = m_flDamage; } // -------------------------------------------------------------------------------------------------- // // Inlines. // -------------------------------------------------------------------------------------------------- // inline CBaseEntity *CMultiDamage::GetTarget() const { return m_hTarget; } inline void CMultiDamage::SetTarget( CBaseEntity *pTarget ) { m_hTarget = pTarget; } #endif // TAKEDAMAGEINFO_H