@@ -85,7 +85,7 @@ public override bool OnUpdate(ServerCharacter clientCharacter)
8585 /// <returns></returns>
8686 private IDamageable DetectFoe ( ServerCharacter parent , ulong foeHint = 0 )
8787 {
88- return GetIdealMeleeFoe ( Config . IsFriendly ^ parent . IsNpc , parent . physicsWrapper . DamageCollider , Config . Range , foeHint ) ;
88+ return GetIdealMeleeFoe ( Config . IsFriendly ^ parent . IsNpc , parent . physicsWrapper . DamageCollider , Config . Range , Config . Radius , foeHint ) ;
8989 }
9090
9191 /// <summary>
@@ -96,25 +96,48 @@ private IDamageable DetectFoe(ServerCharacter parent, ulong foeHint = 0)
9696 /// <param name="isNPC">true if the attacker is an NPC (and therefore should hit PCs). False for the reverse.</param>
9797 /// <param name="ourCollider">The collider of the attacking GameObject.</param>
9898 /// <param name="meleeRange">The range in meters to check for foes.</param>
99+ /// <param name="meleeRadius">The radius in meters to check for foes.</param>
99100 /// <param name="preferredTargetNetworkId">The NetworkObjectId of our preferred foe, or 0 if no preference</param>
100101 /// <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 )
102+ /// <remarks>
103+ /// 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.
104+ /// Also, if multiple targets collide as a result, the target with the highest total damage is prioritized.
105+ /// </remarks>
106+ public static IDamageable GetIdealMeleeFoe ( bool isNPC , Collider ourCollider , float meleeRange , float meleeRadius , ulong preferredTargetNetworkId )
102107 {
103108 RaycastHit [ ] results ;
104- int numResults = ActionUtils . DetectMeleeFoe ( isNPC , ourCollider , meleeRange , out results ) ;
109+ int numResults = 0.0f < meleeRadius
110+ ? ActionUtils . DetectNearbyEntitiesUseSphere ( isNPC , ! isNPC , ourCollider , meleeRange , meleeRadius , out results )
111+ : ActionUtils . DetectNearbyEntities ( isNPC , ! isNPC , ourCollider , meleeRange , out results ) ;
105112
106113 IDamageable foundFoe = null ;
107114
108115 //everything that got hit by the raycast should have an IDamageable component, so we can retrieve that and see if they're appropriate targets.
109116 //we always prefer the hinted foe. If he's still in range, he should take the damage, because he's who the client visualization
110117 //system will play the hit-react on (in case there's any ambiguity).
118+ //if that is not the case, we prioritize the target with the highest total damage.
119+ int maxDamage = int . MinValue ;
120+
111121 for ( int i = 0 ; i < numResults ; i ++ )
112122 {
113123 var damageable = results [ i ] . collider . GetComponent < IDamageable > ( ) ;
114- if ( damageable != null && damageable . IsDamageable ( ) &&
115- ( damageable . NetworkObjectId == preferredTargetNetworkId || foundFoe == null ) )
124+ if ( damageable == null || ! damageable . IsDamageable ( ) )
125+ {
126+ continue ;
127+ }
128+
129+ if ( damageable . NetworkObjectId == preferredTargetNetworkId )
130+ {
131+ foundFoe = damageable ;
132+ maxDamage = int . MaxValue ;
133+ continue ;
134+ }
135+
136+ var totalDamage = damageable . GetTotalDamage ( ) ;
137+ if ( foundFoe == null || maxDamage < totalDamage )
116138 {
117139 foundFoe = damageable ;
140+ maxDamage = totalDamage ;
118141 }
119142 }
120143
0 commit comments