Skip to content

Commit efcca99

Browse files
authored
Merge pull request #994 from Kitsune44/weapons2
Fixes: Weapons and Environment: Revised radiation volume.
2 parents f39ada0 + a0f01b0 commit efcca99

File tree

2 files changed

+58
-14
lines changed

2 files changed

+58
-14
lines changed

src/game/server/swarm/asw_radiation_volume.cpp

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void CASW_Radiation_Volume::Spawn( void )
4444
AddEffects(EF_NODRAW);
4545
SetSolid( SOLID_BBOX );
4646
float boxWidth = m_flBoxWidth;
47-
UTIL_SetSize(this, Vector(-boxWidth,-boxWidth,0),Vector(boxWidth,boxWidth,boxWidth * 2));
47+
UTIL_SetSize( this, Vector( -boxWidth, -boxWidth, 0 ), Vector( boxWidth, boxWidth, boxWidth * 2 ) );
4848
SetCollisionGroup(ASW_COLLISION_GROUP_PASSABLE);
4949
AddSolidFlags(FSOLID_TRIGGER | FSOLID_NOT_SOLID);
5050
SetTouch( &CASW_Radiation_Volume::RadTouch );
@@ -61,25 +61,67 @@ bool CASW_Radiation_Volume::IsValidRadTarget( CBaseEntity *pOther )
6161
return pOther->IsNPC();
6262
}
6363

64-
void CASW_Radiation_Volume::RadTouch( CBaseEntity *pOther )
64+
// Helper centralizing detection logic used by RadTouch and RadTouching
65+
bool CASW_Radiation_Volume::IsInRadiationVolume( CBaseEntity *pEnt )
6566
{
66-
// if other is a valid entity to radiate, add it to our list
67-
if (IsValidRadTarget(pOther) && m_hRadTouching.Find(pOther) == m_hRadTouching.InvalidIndex())
67+
if ( !pEnt )
68+
return false;
69+
70+
// m_flBoxWidth used as radius:
71+
const float flRadius = m_flBoxWidth;
72+
const float flRadiusSqr = flRadius * flRadius;
73+
74+
const Vector vecCenter = GetAbsOrigin();
75+
CCollisionProperty* pEntColl = pEnt->CollisionProp();
76+
CCollisionProperty* pVolColl = CollisionProp();
77+
if ( !pVolColl )
78+
return false;
79+
80+
// compute the nearest point on the other entity to our center (robust for large NPCs)
81+
Vector vecNearest;
82+
if ( pEntColl )
83+
pEntColl->CalcNearestPoint( vecCenter, &vecNearest );
84+
else
85+
vecNearest = pEnt->WorldSpaceCenter();
86+
87+
// If other is a marine, use CYLINDER test:
88+
// - horizontal (XY) distance < radius
89+
// - AND the nearest point must be within our cuboid bounds (so Z is constrained by the volume)
90+
if ( pEnt->Classify() == CLASS_ASW_MARINE )
6891
{
69-
m_hRadTouching.AddToTail(pOther);
70-
if (GetNextThink() == TICK_NEVER_THINK)
71-
SetNextThink( gpGlobals->curtime );
92+
// must be inside vertical bounds (cuboid)
93+
if ( !pVolColl->IsPointInBounds( vecNearest ) )
94+
return false;
95+
96+
// horizontal delta (XY)
97+
Vector vecDelta = vecNearest - vecCenter;
98+
// horizontal distance squared check (circle)
99+
if ( ( vecDelta.x * vecDelta.x + vecDelta.y * vecDelta.y ) >= flRadiusSqr )
100+
return false;
101+
102+
return true;
72103
}
104+
// aliens: full cuboid
105+
return pVolColl->IsPointInBounds( vecNearest );
73106
}
74107

75-
bool CASW_Radiation_Volume::RadTouching(CBaseEntity *pEnt)
108+
void CASW_Radiation_Volume::RadTouch( CBaseEntity* pOther )
76109
{
77-
if (!pEnt || !pEnt->CollisionProp() || !CollisionProp())
78-
return false;
110+
// if other is a valid entity to radiate, add it to our list
111+
if ( !IsValidRadTarget( pOther )
112+
|| m_hRadTouching.Find( pOther ) != m_hRadTouching.InvalidIndex() // avoid duplicates
113+
|| !IsInRadiationVolume( pOther ) )
114+
return;
79115

80-
Vector vecNearest;
81-
pEnt->CollisionProp()->CalcNearestPoint( GetAbsOrigin(), &vecNearest );
82-
return CollisionProp()->IsPointInBounds(vecNearest);
116+
m_hRadTouching.AddToTail( pOther );
117+
if ( GetNextThink() == TICK_NEVER_THINK )
118+
SetNextThink( gpGlobals->curtime );
119+
}
120+
121+
bool CASW_Radiation_Volume::RadTouching( CBaseEntity* pEnt )
122+
{
123+
// simply reuse centralized detection
124+
return IsInRadiationVolume( pEnt );
83125
}
84126

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

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

96138
CBaseEntity *pWeapon = NULL;

src/game/server/swarm/asw_radiation_volume.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class CASW_Radiation_Volume : public CBaseEntity
1313
void RadHurt(CBaseEntity *pEnt);
1414
bool RadTouching(CBaseEntity *pEnt);
1515
bool IsValidRadTarget( CBaseEntity *pOther );
16+
// helper that centralizes the collision/volume checks used by RadTouch and RadTouching
17+
bool IsInRadiationVolume( CBaseEntity *pEnt );
1618

1719
DECLARE_DATADESC();
1820
CUtlVector<EHANDLE> m_hRadTouching;

0 commit comments

Comments
 (0)