@@ -67,20 +67,46 @@ void CASW_Radiation_Volume::RadTouch( CBaseEntity* pOther )
6767 if ( !IsValidRadTarget ( pOther ) )
6868 return ;
6969
70- // Treat m_flBoxWidth as radius:
71- float flRadius = m_flBoxWidth;
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* pOtherColl = pOther->CollisionProp (); // cache
76+ CCollisionProperty* pVolColl = CollisionProp (); // cache
77+ if ( !pVolColl )
78+ return ;
7279
73- // If entity has a collision prop, compute nearest point and test 3D distance (sphere)
74- if ( pOther->CollisionProp () )
80+ // compute the nearest point on the other entity to our center (robust for large NPCs)
81+ Vector vecNearest;
82+ if ( pOtherColl )
83+ pOtherColl->CalcNearestPoint ( vecCenter, &vecNearest );
84+ else
85+ vecNearest = pOther->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 ( pOther->Classify () == CLASS_ASW_MARINE )
7591 {
76- Vector vecNearest;
77- pOther->CollisionProp ()->CalcNearestPoint ( GetAbsOrigin (), &vecNearest );
78-
79- Vector vecDelta = vecNearest - GetAbsOrigin ();
80- if ( vecDelta.Length () > flRadius )
81- return ; // outside the sphere
92+ // must be within our cuboid in Z (IsPointInBounds) and within horizontal radius
93+ if ( pVolColl->IsPointInBounds ( vecNearest ) )
94+ {
95+ // horizontal delta (XY)
96+ Vector vecDelta = vecNearest - vecCenter;
97+ // horizontal distance squared check (circle)
98+ if ( ( vecDelta.x * vecDelta.x + vecDelta.y * vecDelta.y ) >= flRadiusSqr )
99+ return ;
100+ }
101+ }
102+ else
103+ {
104+ // aliens: full cuboid check only
105+ if ( !pVolColl->IsPointInBounds ( vecNearest ) )
106+ return ;
82107 }
83108
109+ // avoid duplicates
84110 if ( m_hRadTouching.Find ( pOther ) == m_hRadTouching.InvalidIndex () )
85111 {
86112 m_hRadTouching.AddToTail ( pOther );
@@ -91,22 +117,45 @@ void CASW_Radiation_Volume::RadTouch( CBaseEntity* pOther )
91117
92118bool CASW_Radiation_Volume::RadTouching ( CBaseEntity* pEnt )
93119{
94- if ( !pEnt || !pEnt-> CollisionProp () )
120+ if ( !pEnt )
95121 return false ;
96122
97- // Treat m_flBoxWidth as radius:
98- float flRadius = m_flBoxWidth;
123+ // m_flBoxWidth used as radius:
124+ const float flRadius = m_flBoxWidth;
125+ const float flRadiusSqr = flRadius * flRadius;
126+
127+ const Vector vecCenter = GetAbsOrigin ();
128+ CCollisionProperty* pEntColl = pEnt->CollisionProp (); // cache
129+ CCollisionProperty* pVolColl = CollisionProp (); // cache
130+ if ( !pVolColl )
131+ return false ;
99132
100- // nearest point on the entity to our center
133+ // compute the nearest point on the other entity to our center (robust for large NPCs)
101134 Vector vecNearest;
102- pEnt->CollisionProp ()->CalcNearestPoint ( GetAbsOrigin (), &vecNearest );
135+ if ( pEntColl )
136+ pEntColl->CalcNearestPoint ( vecCenter, &vecNearest );
137+ else
138+ vecNearest = pEnt->WorldSpaceCenter ();
139+
140+ // If other is a marine, use CYLINDER test:
141+ // - horizontal (XY) distance < radius
142+ // - AND the nearest point must be within our cuboid bounds (so Z is constrained by the volume)
143+ if ( pEnt->Classify () == CLASS_ASW_MARINE )
144+ {
145+ // must be inside vertical bounds (cuboid)
146+ if ( !pVolColl->IsPointInBounds ( vecNearest ) )
147+ return false ;
103148
104- // Sphere test (3D)
105- Vector vecDelta = vecNearest - GetAbsOrigin ();
106- if ( vecDelta.Length () > flRadius )
107- return false ; // outside the sphere
149+ // horizontal delta (XY)
150+ Vector vecDelta = vecNearest - vecCenter;
151+ // horizontal distance squared check (circle)
152+ if ( ( vecDelta.x * vecDelta.x + vecDelta.y * vecDelta.y ) >= flRadiusSqr )
153+ return false ;
108154
109- return true ;
155+ return true ;
156+ }
157+ // aliens: full cuboid
158+ return pVolColl->IsPointInBounds ( vecNearest );
110159}
111160
112161void CASW_Radiation_Volume::RadHurt (CBaseEntity *pEnt)
0 commit comments