@@ -69,6 +69,7 @@ public override bool OnUpdate(ServerCharacter clientCharacter)
6969 if ( ! m_ExecutionFired && ( Time . time - TimeStarted ) >= Config . ExecTimeSeconds )
7070 {
7171 m_ExecutionFired = true ;
72+
7273 var foe = DetectFoe ( clientCharacter , m_ProvisionalTarget ) ;
7374 if ( foe != null )
7475 {
@@ -85,7 +86,7 @@ public override bool OnUpdate(ServerCharacter clientCharacter)
8586 /// <returns></returns>
8687 private IDamageable DetectFoe ( ServerCharacter parent , ulong foeHint = 0 )
8788 {
88- return GetIdealMeleeFoe ( Config . IsFriendly ^ parent . IsNpc , parent . physicsWrapper . DamageCollider , Config . Range , foeHint ) ;
89+ return GetIdealMeleeFoe ( Config . IsFriendly ^ parent . IsNpc , parent . physicsWrapper . DamageCollider , Config . Range , Config . Radius , foeHint ) ;
8990 }
9091
9192 /// <summary>
@@ -96,25 +97,48 @@ private IDamageable DetectFoe(ServerCharacter parent, ulong foeHint = 0)
9697 /// <param name="isNPC">true if the attacker is an NPC (and therefore should hit PCs). False for the reverse.</param>
9798 /// <param name="ourCollider">The collider of the attacking GameObject.</param>
9899 /// <param name="meleeRange">The range in meters to check for foes.</param>
100+ /// <param name="meleeRadius">The radius in meters to check for foes.</param>
99101 /// <param name="preferredTargetNetworkId">The NetworkObjectId of our preferred foe, or 0 if no preference</param>
100102 /// <returns>ideal target's IDamageable, or null if no valid target found</returns>
101- public static IDamageable GetIdealMeleeFoe ( bool isNPC , Collider ourCollider , float meleeRange , ulong preferredTargetNetworkId )
103+ /// <remarks>
104+ /// If a Radius value is set (greater than 0), collision checking will be done with a Sphere the size of the Radius, not the size of the Box.
105+ /// Also, if multiple targets collide as a result, the target with the highest total damage is prioritized.
106+ /// </remarks>
107+ public static IDamageable GetIdealMeleeFoe ( bool isNPC , Collider ourCollider , float meleeRange , float meleeRadius , ulong preferredTargetNetworkId )
102108 {
103109 RaycastHit [ ] results ;
104- int numResults = ActionUtils . DetectMeleeFoe ( isNPC , ourCollider , meleeRange , out results ) ;
110+ int numResults = 0.0f < meleeRadius
111+ ? ActionUtils . DetectNearbyEntitiesUseSphere ( isNPC , ! isNPC , ourCollider , meleeRange , meleeRadius , out results )
112+ : ActionUtils . DetectNearbyEntities ( isNPC , ! isNPC , ourCollider , meleeRange , out results ) ;
105113
106114 IDamageable foundFoe = null ;
107115
108116 //everything that got hit by the raycast should have an IDamageable component, so we can retrieve that and see if they're appropriate targets.
109117 //we always prefer the hinted foe. If he's still in range, he should take the damage, because he's who the client visualization
110118 //system will play the hit-react on (in case there's any ambiguity).
119+ //if that is not the case, we prioritize the target with the highest total damage.
120+ int maxDamage = int . MinValue ;
121+
111122 for ( int i = 0 ; i < numResults ; i ++ )
112123 {
113124 var damageable = results [ i ] . collider . GetComponent < IDamageable > ( ) ;
114- if ( damageable != null && damageable . IsDamageable ( ) &&
115- ( damageable . NetworkObjectId == preferredTargetNetworkId || foundFoe == null ) )
125+ if ( damageable == null || ! damageable . IsDamageable ( ) )
126+ {
127+ continue ;
128+ }
129+
130+ if ( damageable . NetworkObjectId == preferredTargetNetworkId )
131+ {
132+ foundFoe = damageable ;
133+ maxDamage = int . MaxValue ;
134+ continue ;
135+ }
136+
137+ var totalDamage = damageable . GetTotalDamage ( ) ;
138+ if ( foundFoe == null || maxDamage < totalDamage )
116139 {
117140 foundFoe = damageable ;
141+ maxDamage = totalDamage ;
118142 }
119143 }
120144
0 commit comments