text: //========= Copyright Valve Corporation, All rights reserved. ============//
  //
  // Purpose: 
  //
  // $NoKeywords: $
  //=============================================================================//
  
  #ifndef FIRE_DAMAGE_MGR_H
  #define FIRE_DAMAGE_MGR_H
  #ifdef _WIN32
  #pragma once
  #endif
  
  
  #include "igamesystem.h"
  #include "utllinkedlist.h"
  #include "ehandle.h"
  
  
  class CEntityBurnEffect;
  
  
  // ------------------------------------------------------------------------------------------ //
  // CFireDamageMgr.
  //
  // This class manages fire damage being applied to entities. It uses velocity, acceleration,
  // and decay to model fire damage building up, and it puts a cap on the maximum amount of damage
  // an entity can take from fire during a given frame.
  // ------------------------------------------------------------------------------------------ //
  
  class CFireDamageMgr : public CAutoGameSystem
  {
  // Overrides.
  public:
  
  	virtual bool	Init();
  	virtual void	FrameUpdatePostEntityThink();
  
  
  public:
  	// Apply fire damage to an entity. flDamageAccel is in units per second, so in the absence of
  	// decay, it equals velocity increase per second.
  	//
  	// NOTE: the damage acceleration should always be greater than the decay per second, or no damage
  	//       will be applied since it will decay faster than 
  	void		AddDamage( CBaseEntity *pTarget, CBaseEntity *pAttacker, float flDamageAccel, bool bMakeBurnEffect );
  
  
  private:
  	class CDamageAttacker
  	{
  	public:
  		void	Init( CBaseEntity *pAttacker, float flVelocity )
  		{
  			m_hAttacker = pAttacker;
  			m_flVelocity = flVelocity;
  			m_flDamageSum = 0;
  		}		
  		
  		EHANDLE	m_hAttacker;
  		float	m_flVelocity;	// Current damage velocity.
  		
  		float	m_flDamageSum;	// Damage is summed up and applied a couple times per second instead of 
  								// each frame since fractional damage is rounded to 1.
  	};
  
  	class CDamageEnt
  	{
  	public:
  		enum
  		{
  			MAX_ATTACKERS = 4
  		};
  
  		bool				m_bWasAlive;
  
  		EHANDLE				m_hEnt;
  		CHandle<CEntityBurnEffect>	m_pBurnEffect;
  		
  		// Each attacker gets credit for a portion of 
  		CDamageAttacker	m_Attackers[MAX_ATTACKERS];
  		int				m_nAttackers;
  	};
  
  
  private:
  
  	void		ApplyCollectedDamage( CFireDamageMgr::CDamageEnt *pEnt, int iAttacker );
  	void		RemoveDamageEnt( int iEnt );
  
  
  private:
  	
  	CUtlLinkedList<CDamageEnt,int>	m_DamageEnts;
  
  	float	m_flMaxDamagePerSecond;
  	float 	m_flDecayConstant;
  
  	// This counts down to zero so we only apply fire damage every so often.
  	float	m_flApplyDamageCountdown;
  };
  
  
  // Returns true if the entity is burnable by the specified team.
  bool IsBurnableEnt( CBaseEntity *pEntity, int iTeam );
  
  
  // This is used by the flamethrower and the burning gasoline blobs to find entities to burn.
  int FindBurnableEntsInSphere(
  	CBaseEntity **ents,
  	float *dists,
  	int nMaxEnts,
  	const Vector &vecCenter,
  	float flSearchRadius,
  	CBaseEntity *pOwner );
  
  
  CFireDamageMgr* GetFireDamageMgr();
  
  
  #endif // FIRE_DAMAGE_MGR_H
  