sqwarmed/sdk_src/game/server/swarm/asw_radiation_volume.cpp

109 lines
2.8 KiB
C++

#include "cbase.h"
#include "asw_radiation_volume.h"
#include "asw_shareddefs.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
LINK_ENTITY_TO_CLASS( asw_radiation_volume, CASW_Radiation_Volume );
#define RAD_DAMAGE_INTERVAL 1.0f
#define ASW_RAD_DAMAGE 20
BEGIN_DATADESC( CASW_Radiation_Volume )
DEFINE_FUNCTION(RadTouch),
DEFINE_THINKFUNC(RadThink),
DEFINE_FIELD(m_hCreator, FIELD_EHANDLE),
END_DATADESC()
CASW_Radiation_Volume::CASW_Radiation_Volume()
{
}
void CASW_Radiation_Volume::Spawn( void )
{
BaseClass::Spawn();
// make us invisible, a cube, non solid, but still firing touch triggers
AddEffects(EF_NODRAW);
SetSolid( SOLID_BBOX );
float boxWidth = 100.0f;
UTIL_SetSize(this, Vector(-boxWidth,-boxWidth,0),Vector(boxWidth,boxWidth,boxWidth * 2));
SetCollisionGroup(ASW_COLLISION_GROUP_PASSABLE);
AddSolidFlags(FSOLID_TRIGGER);
SetTouch( &CASW_Radiation_Volume::RadTouch );
SetThink( &CASW_Radiation_Volume::RadThink );
SetNextThink( TICK_NEVER_THINK );
}
bool CASW_Radiation_Volume::IsValidRadTarget( CBaseEntity *pOther )
{
if (!pOther)
return false;
return pOther->IsNPC();
}
void CASW_Radiation_Volume::RadTouch( CBaseEntity *pOther )
{
// if other is a valid entity to radiate, add it to our list
if (IsValidRadTarget(pOther) && m_hRadTouching.Find(pOther) == m_hRadTouching.InvalidIndex())
{
m_hRadTouching.AddToTail(pOther);
if (GetNextThink() == TICK_NEVER_THINK)
SetNextThink( gpGlobals->curtime );
}
}
bool CASW_Radiation_Volume::RadTouching(CBaseEntity *pEnt)
{
if (!pEnt || !pEnt->CollisionProp() || !CollisionProp())
return false;
Vector vecNearest;
pEnt->CollisionProp()->CalcNearestPoint( GetAbsOrigin(), &vecNearest );
return CollisionProp()->IsPointInBounds(vecNearest);
}
void CASW_Radiation_Volume::RadHurt(CBaseEntity *pEnt)
{
if (!pEnt)
return;
CBaseEntity *pAttacker = this;
if (m_hCreator.Get() && pEnt->Classify() != CLASS_ASW_MARINE) // don't deal friendly fire damage from rad barrels
pAttacker = m_hCreator.Get();
float fDamage = ASW_RAD_DAMAGE;
if (pEnt->Classify() == CLASS_ASW_MARINE)
fDamage *= 0.5f;
pEnt->TakeDamage( CTakeDamageInfo( this, pAttacker, fDamage, DMG_RADIATION ) );
}
void CASW_Radiation_Volume::RadThink()
{
// remove people who aren't in our volume
for (int i = 0; i < m_hRadTouching.Count();)
{
if (!m_hRadTouching[i] || m_hRadTouching[i]->GetHealth()<=0
|| !RadTouching(m_hRadTouching[i]))
{
m_hRadTouching.Remove( i );
}
else
{
i++;
}
}
// go through our list, hurting people
for (int i = 0; i < m_hRadTouching.Count(); i++)
{
RadHurt(m_hRadTouching[i]);
}
if (m_hRadTouching.Count() > 0)
{
SetNextThink( gpGlobals->curtime + RAD_DAMAGE_INTERVAL );
}
}