Fix the callers of GetEffectiveAttackRange's out-of-reach range

Follows db23584fc3 - the caller of GetEffectiveAttackRange's didn't
really use the NEVER_IN_RANGE result properly.
The C++ engine does not handle Infinity (treated as 0).
This also changes MoveToTargetAttackRange to explicitly try to get
closer if the parabolic range is not in range, but it seems like a flat
range could - on the assumption that once we get closer, the terrain
height difference is lower.
This commit is contained in:
Lancelot de Ferrière
2026-08-18 15:01:39 +02:00
committed by wraitii
parent 56f94a6d4d
commit 2cc0cf457a
2 changed files with 14 additions and 4 deletions
@@ -572,7 +572,9 @@ Attack.prototype.GetRange = function(type)
* for elevation and projectile physics where applicable.
* @param {number} target - The target entity ID.
* @param {string} type - The attack type.
* @return {{ min: number, max: number }} - The min and max effective range.
* @return {{ min: number, max: number }} - The min and max effective range,
* or { Infinity, 0 } if the target cannot be reached on a parabolic
* trajectory given the current terrain height difference.
*/
Attack.prototype.GetEffectiveAttackRange = function(target, type)
{
@@ -931,6 +933,10 @@ Attack.prototype.PerformAttack = function(type, target)
Attack.prototype.IsTargetInRange = function(target, type)
{
const range = this.GetEffectiveAttackRange(target, type);
// Out of parabolic reach: GetEffectiveAttackRange returns { Infinity, 0 } in that case.
if (range.min > range.max)
return false;
return Engine.QueryInterface(SYSTEM_ENTITY, IID_ObstructionManager).IsInTargetRange(
this.entity, target, range.min, range.max, false);
};
@@ -5187,15 +5187,19 @@ UnitAI.prototype.MoveToTargetAttackRange = function(target, type)
const flatRange = cmpAttack.GetRange(type);
const effectiveRange = cmpAttack.GetEffectiveAttackRange(target, type);
if (effectiveRange.max < 0)
return false;
// Out of parabolic range: assume the terrain height difference is to blame,
// and close in to reassess from there.
if (effectiveRange.min > effectiveRange.max)
return cmpUnitMotion.MoveToTargetRange(target, flatRange.min,
Math.max(flatRange.min, flatRange.max / 2));
// The parabola changes while walking so be cautious:
const guessedMaxRange = effectiveRange.max > flatRange.max ?
(flatRange.max + effectiveRange.max) / 2 :
effectiveRange.max;
return cmpUnitMotion && cmpUnitMotion.MoveToTargetRange(target, effectiveRange.min, guessedMaxRange);
return cmpUnitMotion.MoveToTargetRange(target, effectiveRange.min, guessedMaxRange);
};
UnitAI.prototype.MoveToTargetRangeExplicit = function(target, min, max)