You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.7 KiB
109 lines
2.7 KiB
#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 ); |
|
} |
|
} |