Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 56 additions & 14 deletions src/game/server/swarm/asw_radiation_volume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void CASW_Radiation_Volume::Spawn( void )
AddEffects(EF_NODRAW);
SetSolid( SOLID_BBOX );
float boxWidth = m_flBoxWidth;
UTIL_SetSize(this, Vector(-boxWidth,-boxWidth,0),Vector(boxWidth,boxWidth,boxWidth * 2));
UTIL_SetSize( this, Vector( -boxWidth, -boxWidth, 0 ), Vector( boxWidth, boxWidth, boxWidth * 2 ) );
SetCollisionGroup(ASW_COLLISION_GROUP_PASSABLE);
AddSolidFlags(FSOLID_TRIGGER | FSOLID_NOT_SOLID);
SetTouch( &CASW_Radiation_Volume::RadTouch );
Expand All @@ -61,25 +61,67 @@ bool CASW_Radiation_Volume::IsValidRadTarget( CBaseEntity *pOther )
return pOther->IsNPC();
}

void CASW_Radiation_Volume::RadTouch( CBaseEntity *pOther )
// Helper centralizing detection logic used by RadTouch and RadTouching
bool CASW_Radiation_Volume::IsInRadiationVolume( CBaseEntity *pEnt )
{
// if other is a valid entity to radiate, add it to our list
if (IsValidRadTarget(pOther) && m_hRadTouching.Find(pOther) == m_hRadTouching.InvalidIndex())
if ( !pEnt )
return false;

// m_flBoxWidth used as radius:
const float flRadius = m_flBoxWidth;
const float flRadiusSqr = flRadius * flRadius;

const Vector vecCenter = GetAbsOrigin();
CCollisionProperty* pEntColl = pEnt->CollisionProp();
CCollisionProperty* pVolColl = CollisionProp();
if ( !pVolColl )
return false;

// compute the nearest point on the other entity to our center (robust for large NPCs)
Vector vecNearest;
if ( pEntColl )
pEntColl->CalcNearestPoint( vecCenter, &vecNearest );
else
vecNearest = pEnt->WorldSpaceCenter();

// If other is a marine, use CYLINDER test:
// - horizontal (XY) distance < radius
// - AND the nearest point must be within our cuboid bounds (so Z is constrained by the volume)
if ( pEnt->Classify() == CLASS_ASW_MARINE )
{
m_hRadTouching.AddToTail(pOther);
if (GetNextThink() == TICK_NEVER_THINK)
SetNextThink( gpGlobals->curtime );
// must be inside vertical bounds (cuboid)
if ( !pVolColl->IsPointInBounds( vecNearest ) )
return false;

// horizontal delta (XY)
Vector vecDelta = vecNearest - vecCenter;
// horizontal distance squared check (circle)
if ( ( vecDelta.x * vecDelta.x + vecDelta.y * vecDelta.y ) >= flRadiusSqr )
return false;

return true;
}
// aliens: full cuboid
return pVolColl->IsPointInBounds( vecNearest );
}

bool CASW_Radiation_Volume::RadTouching(CBaseEntity *pEnt)
void CASW_Radiation_Volume::RadTouch( CBaseEntity* pOther )
{
if (!pEnt || !pEnt->CollisionProp() || !CollisionProp())
return false;
// if other is a valid entity to radiate, add it to our list
if ( !IsValidRadTarget( pOther )
|| m_hRadTouching.Find( pOther ) != m_hRadTouching.InvalidIndex() // avoid duplicates
|| !IsInRadiationVolume( pOther ) )
return;

Vector vecNearest;
pEnt->CollisionProp()->CalcNearestPoint( GetAbsOrigin(), &vecNearest );
return CollisionProp()->IsPointInBounds(vecNearest);
m_hRadTouching.AddToTail( pOther );
if ( GetNextThink() == TICK_NEVER_THINK )
SetNextThink( gpGlobals->curtime );
}

bool CASW_Radiation_Volume::RadTouching( CBaseEntity* pEnt )
{
// simply reuse centralized detection
return IsInRadiationVolume( pEnt );
}

void CASW_Radiation_Volume::RadHurt(CBaseEntity *pEnt)
Expand All @@ -90,7 +132,7 @@ void CASW_Radiation_Volume::RadHurt(CBaseEntity *pEnt)
int iDamageType = DMG_RADIATION;

CBaseEntity *pAttacker = this;
if (m_hCreator.Get() && pEnt->Classify() != CLASS_ASW_MARINE) // don't deal friendly fire damage from rad barrels
if (m_hCreator.Get() && pEnt->Classify() != CLASS_ASW_MARINE) // don't deal friendly fire damage from rad barrels
pAttacker = m_hCreator.Get();

CBaseEntity *pWeapon = NULL;
Expand Down
2 changes: 2 additions & 0 deletions src/game/server/swarm/asw_radiation_volume.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class CASW_Radiation_Volume : public CBaseEntity
void RadHurt(CBaseEntity *pEnt);
bool RadTouching(CBaseEntity *pEnt);
bool IsValidRadTarget( CBaseEntity *pOther );
// helper that centralizes the collision/volume checks used by RadTouch and RadTouching
bool IsInRadiationVolume( CBaseEntity *pEnt );

DECLARE_DATADESC();
CUtlVector<EHANDLE> m_hRadTouching;
Expand Down