@@ -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
85127void 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 ;
0 commit comments