@@ -63,20 +63,32 @@ protected override void DoImpact(WPos pos, Actor firedBy, WarheadArgs args)
6363 if ( ! IsValidAgainst ( victim , firedBy ) )
6464 continue ;
6565
66- var closestActiveShape = victim . TraitsImplementing < HitShape > ( )
67- . Where ( Exts . IsTraitEnabled )
68- . Select ( s => ( HitShape : s , Distance : s . DistanceFromEdge ( victim , pos ) ) )
69- . MinByOrDefault ( s => s . Distance ) ;
66+ HitShape closestActiveShape = null ;
67+ var closestDistance = int . MaxValue ;
68+
69+ // PERF: Avoid using TraitsImplementing<HitShape> that needs to find the actor in the trait dictionary.
70+ foreach ( var targetPos in victim . EnabledTargetablePositions )
71+ {
72+ if ( targetPos is HitShape h )
73+ {
74+ var distance = h . DistanceFromEdge ( victim , pos ) . Length ;
75+ if ( distance < closestDistance )
76+ {
77+ closestDistance = distance ;
78+ closestActiveShape = h ;
79+ }
80+ }
81+ }
7082
7183 // Cannot be damaged without an active HitShape.
72- if ( closestActiveShape . HitShape == null )
84+ if ( closestActiveShape == null )
7385 continue ;
7486
7587 var falloffDistance = 0 ;
7688 switch ( DamageCalculationType )
7789 {
7890 case DamageCalculationType . HitShape :
79- falloffDistance = closestActiveShape . Distance . Length ;
91+ falloffDistance = closestDistance ;
8092 break ;
8193 case DamageCalculationType . ClosestTargetablePosition :
8294 falloffDistance = victim . GetTargetablePositions ( ) . Select ( x => ( x - pos ) . Length ) . Min ( ) ;
@@ -108,7 +120,7 @@ protected override void DoImpact(WPos pos, Actor firedBy, WarheadArgs args)
108120 ImpactOrientation = impactOrientation ,
109121 } ;
110122
111- InflictDamage ( victim , firedBy , closestActiveShape . HitShape , updatedWarheadArgs ) ;
123+ InflictDamage ( victim , firedBy , closestActiveShape , updatedWarheadArgs ) ;
112124 }
113125 }
114126
0 commit comments